/*
 * Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
 * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
 */

@file:Suppress("UNUSED_PARAMETER")

package org.jetbrains.kotlin.incremental

import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.builtins.BuiltInsProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
import org.jetbrains.kotlin.metadata.java.JavaClassProtoBuf
import org.jetbrains.kotlin.metadata.js.JsProtoBuf
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
import org.jetbrains.kotlin.metadata.serialization.Interner
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.getClassId
import java.util.*

/** This file is generated by org.jetbrains.kotlin.generators.protobuf.GenerateProtoBufCompare. DO NOT MODIFY MANUALLY */

open class ProtoCompareGenerated(
    val oldNameResolver: NameResolver,
    val newNameResolver: NameResolver,
    oldTypeTable: ProtoBuf.TypeTable?,
    newTypeTable: ProtoBuf.TypeTable?
) {
    private val strings = Interner<String>()
    val oldStringIndexesMap: MutableMap<Int, Int> = hashMapOf()
    val newStringIndexesMap: MutableMap<Int, Int> = hashMapOf()
    val oldClassIdIndexesMap: MutableMap<Int, Int> = hashMapOf()
    val newClassIdIndexesMap: MutableMap<Int, Int> = hashMapOf()
    val oldTypeTable: ProtoBuf.TypeTable = oldTypeTable ?: ProtoBuf.TypeTable.getDefaultInstance()
    val newTypeTable: ProtoBuf.TypeTable = newTypeTable ?: ProtoBuf.TypeTable.getDefaultInstance()

    private val classIds = Interner<ClassId>()

    open fun checkEquals(old: ProtoBuf.Package, new: ProtoBuf.Package): Boolean {
        if (!checkEqualsPackageFunction(old, new)) return false

        if (!checkEqualsPackageProperty(old, new)) return false

        if (!checkEqualsPackageTypeAlias(old, new)) return false

        if (old.hasVersionRequirementTable() != new.hasVersionRequirementTable()) return false
        if (old.hasVersionRequirementTable()) {
            if (!checkEquals(old.versionRequirementTable, new.versionRequirementTable)) return false
        }

        if (old.hasExtension(JvmProtoBuf.packageModuleName) != new.hasExtension(JvmProtoBuf.packageModuleName)) return false
        if (old.hasExtension(JvmProtoBuf.packageModuleName)) {
            if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) return false
        }

        if (old.getExtensionCount(JvmProtoBuf.packageLocalVariable) != new.getExtensionCount(JvmProtoBuf.packageLocalVariable)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
                if (!checkEquals(old.getExtension(JvmProtoBuf.packageLocalVariable, i), new.getExtension(JvmProtoBuf.packageLocalVariable, i))) return false
            }
        }

        if (old.hasExtension(JsProtoBuf.packageFqName) != new.hasExtension(JsProtoBuf.packageFqName)) return false
        if (old.hasExtension(JsProtoBuf.packageFqName)) {
            if (old.getExtension(JsProtoBuf.packageFqName) != new.getExtension(JsProtoBuf.packageFqName)) return false
        }

        if (old.hasExtension(BuiltInsProtoBuf.packageFqName) != new.hasExtension(BuiltInsProtoBuf.packageFqName)) return false
        if (old.hasExtension(BuiltInsProtoBuf.packageFqName)) {
            if (old.getExtension(BuiltInsProtoBuf.packageFqName) != new.getExtension(BuiltInsProtoBuf.packageFqName)) return false
        }

        if (old.hasExtension(KlibMetadataProtoBuf.packageFqName) != new.hasExtension(KlibMetadataProtoBuf.packageFqName)) return false
        if (old.hasExtension(KlibMetadataProtoBuf.packageFqName)) {
            if (old.getExtension(KlibMetadataProtoBuf.packageFqName) != new.getExtension(KlibMetadataProtoBuf.packageFqName)) return false
        }

        return true
    }
    enum class ProtoBufPackageKind {
        FUNCTION_LIST,
        PROPERTY_LIST,
        TYPE_ALIAS_LIST,
        VERSION_REQUIREMENT_TABLE,
        JVM_EXT_PACKAGE_MODULE_NAME,
        JVM_EXT_PACKAGE_LOCAL_VARIABLE_LIST,
        JS_EXT_PACKAGE_FQ_NAME,
        BUILT_INS_EXT_PACKAGE_FQ_NAME,
        KLIB_EXT_PACKAGE_FQ_NAME
    }

    fun difference(old: ProtoBuf.Package, new: ProtoBuf.Package): EnumSet<ProtoBufPackageKind> {
        val result = EnumSet.noneOf(ProtoBufPackageKind::class.java)

        if (!checkEqualsPackageFunction(old, new)) result.add(ProtoBufPackageKind.FUNCTION_LIST)

        if (!checkEqualsPackageProperty(old, new)) result.add(ProtoBufPackageKind.PROPERTY_LIST)

        if (!checkEqualsPackageTypeAlias(old, new)) result.add(ProtoBufPackageKind.TYPE_ALIAS_LIST)

        if (old.hasVersionRequirementTable() != new.hasVersionRequirementTable()) result.add(ProtoBufPackageKind.VERSION_REQUIREMENT_TABLE)
        if (old.hasVersionRequirementTable()) {
            if (!checkEquals(old.versionRequirementTable, new.versionRequirementTable)) result.add(ProtoBufPackageKind.VERSION_REQUIREMENT_TABLE)
        }

        if (old.hasExtension(JvmProtoBuf.packageModuleName) != new.hasExtension(JvmProtoBuf.packageModuleName)) result.add(ProtoBufPackageKind.JVM_EXT_PACKAGE_MODULE_NAME)
        if (old.hasExtension(JvmProtoBuf.packageModuleName)) {
            if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) result.add(ProtoBufPackageKind.JVM_EXT_PACKAGE_MODULE_NAME)
        }

        if (old.getExtensionCount(JvmProtoBuf.packageLocalVariable) != new.getExtensionCount(JvmProtoBuf.packageLocalVariable)) {
            result.add(ProtoBufPackageKind.JVM_EXT_PACKAGE_LOCAL_VARIABLE_LIST)
        }
        else {
            for(i in 0..old.getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
                if (!checkEquals(old.getExtension(JvmProtoBuf.packageLocalVariable, i), new.getExtension(JvmProtoBuf.packageLocalVariable, i))) result.add(ProtoBufPackageKind.JVM_EXT_PACKAGE_LOCAL_VARIABLE_LIST)
            }
        }

        if (old.hasExtension(JsProtoBuf.packageFqName) != new.hasExtension(JsProtoBuf.packageFqName)) result.add(ProtoBufPackageKind.JS_EXT_PACKAGE_FQ_NAME)
        if (old.hasExtension(JsProtoBuf.packageFqName)) {
            if (old.getExtension(JsProtoBuf.packageFqName) != new.getExtension(JsProtoBuf.packageFqName)) result.add(ProtoBufPackageKind.JS_EXT_PACKAGE_FQ_NAME)
        }

        if (old.hasExtension(BuiltInsProtoBuf.packageFqName) != new.hasExtension(BuiltInsProtoBuf.packageFqName)) result.add(ProtoBufPackageKind.BUILT_INS_EXT_PACKAGE_FQ_NAME)
        if (old.hasExtension(BuiltInsProtoBuf.packageFqName)) {
            if (old.getExtension(BuiltInsProtoBuf.packageFqName) != new.getExtension(BuiltInsProtoBuf.packageFqName)) result.add(ProtoBufPackageKind.BUILT_INS_EXT_PACKAGE_FQ_NAME)
        }

        if (old.hasExtension(KlibMetadataProtoBuf.packageFqName) != new.hasExtension(KlibMetadataProtoBuf.packageFqName)) result.add(ProtoBufPackageKind.KLIB_EXT_PACKAGE_FQ_NAME)
        if (old.hasExtension(KlibMetadataProtoBuf.packageFqName)) {
            if (old.getExtension(KlibMetadataProtoBuf.packageFqName) != new.getExtension(KlibMetadataProtoBuf.packageFqName)) result.add(ProtoBufPackageKind.KLIB_EXT_PACKAGE_FQ_NAME)
        }

        return result
    }

    open fun checkEquals(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.hasFlags() != new.hasFlags()) return false
        if (old.hasFlags()) {
            if (old.flags != new.flags) return false
        }

        if (!checkClassIdEquals(old.fqName, new.fqName)) return false

        if (old.hasCompanionObjectName() != new.hasCompanionObjectName()) return false
        if (old.hasCompanionObjectName()) {
            if (!checkStringEquals(old.companionObjectName, new.companionObjectName)) return false
        }

        if (!checkEqualsClassTypeParameter(old, new)) return false

        if (!checkEqualsClassSupertype(old, new)) return false

        if (!checkEqualsClassSupertypeId(old, new)) return false

        if (!checkEqualsClassNestedClassName(old, new)) return false

        if (!checkEqualsClassContextReceiverType(old, new)) return false

        if (!checkEqualsClassContextReceiverTypeId(old, new)) return false

        if (!checkEqualsClassConstructor(old, new)) return false

        if (!checkEqualsClassFunction(old, new)) return false

        if (!checkEqualsClassProperty(old, new)) return false

        if (!checkEqualsClassTypeAlias(old, new)) return false

        if (!checkEqualsClassEnumEntry(old, new)) return false

        if (!checkEqualsClassSealedSubclassFqName(old, new)) return false

        if (old.hasInlineClassUnderlyingPropertyName() != new.hasInlineClassUnderlyingPropertyName()) return false
        if (old.hasInlineClassUnderlyingPropertyName()) {
            if (!checkStringEquals(old.inlineClassUnderlyingPropertyName, new.inlineClassUnderlyingPropertyName)) return false
        }

        if (old.hasInlineClassUnderlyingType() != new.hasInlineClassUnderlyingType()) return false
        if (old.hasInlineClassUnderlyingType()) {
            if (!checkEquals(old.inlineClassUnderlyingType, new.inlineClassUnderlyingType)) return false
        }

        if (old.hasInlineClassUnderlyingTypeId() != new.hasInlineClassUnderlyingTypeId()) return false
        if (old.hasInlineClassUnderlyingTypeId()) {
            if (!checkEquals(oldTypeTable.getType(old.inlineClassUnderlyingTypeId), newTypeTable.getType(new.inlineClassUnderlyingTypeId))) return false
        }

        if (!checkEqualsClassMultiFieldValueClassUnderlyingName(old, new)) return false

        if (!checkEqualsClassMultiFieldValueClassUnderlyingType(old, new)) return false

        if (!checkEqualsClassMultiFieldValueClassUnderlyingTypeId(old, new)) return false

        if (!checkEqualsClassVersionRequirement(old, new)) return false

        if (old.hasVersionRequirementTable() != new.hasVersionRequirementTable()) return false
        if (old.hasVersionRequirementTable()) {
            if (!checkEquals(old.versionRequirementTable, new.versionRequirementTable)) return false
        }

        if (old.hasExtension(JvmProtoBuf.classModuleName) != new.hasExtension(JvmProtoBuf.classModuleName)) return false
        if (old.hasExtension(JvmProtoBuf.classModuleName)) {
            if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) return false
        }

        if (old.getExtensionCount(JvmProtoBuf.classLocalVariable) != new.getExtensionCount(JvmProtoBuf.classLocalVariable)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
                if (!checkEquals(old.getExtension(JvmProtoBuf.classLocalVariable, i), new.getExtension(JvmProtoBuf.classLocalVariable, i))) return false
            }
        }

        if (old.hasExtension(JvmProtoBuf.anonymousObjectOriginName) != new.hasExtension(JvmProtoBuf.anonymousObjectOriginName)) return false
        if (old.hasExtension(JvmProtoBuf.anonymousObjectOriginName)) {
            if (!checkStringEquals(old.getExtension(JvmProtoBuf.anonymousObjectOriginName), new.getExtension(JvmProtoBuf.anonymousObjectOriginName))) return false
        }

        if (old.hasExtension(JvmProtoBuf.jvmClassFlags) != new.hasExtension(JvmProtoBuf.jvmClassFlags)) return false
        if (old.hasExtension(JvmProtoBuf.jvmClassFlags)) {
            if (old.getExtension(JvmProtoBuf.jvmClassFlags) != new.getExtension(JvmProtoBuf.jvmClassFlags)) return false
        }

        if (old.getExtensionCount(JsProtoBuf.classAnnotation) != new.getExtensionCount(JsProtoBuf.classAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(JsProtoBuf.classAnnotation) - 1) {
                if (!checkEquals(old.getExtension(JsProtoBuf.classAnnotation, i), new.getExtension(JsProtoBuf.classAnnotation, i))) return false
            }
        }

        if (old.hasExtension(JsProtoBuf.classContainingFileId) != new.hasExtension(JsProtoBuf.classContainingFileId)) return false
        if (old.hasExtension(JsProtoBuf.classContainingFileId)) {
            if (old.getExtension(JsProtoBuf.classContainingFileId) != new.getExtension(JsProtoBuf.classContainingFileId)) return false
        }

        if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateClass) != new.hasExtension(JavaClassProtoBuf.isPackagePrivateClass)) return false
        if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateClass)) {
            if (old.getExtension(JavaClassProtoBuf.isPackagePrivateClass) != new.getExtension(JavaClassProtoBuf.isPackagePrivateClass)) return false
        }

        if (old.getExtensionCount(BuiltInsProtoBuf.classAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.classAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.classAnnotation) - 1) {
                if (!checkEquals(old.getExtension(BuiltInsProtoBuf.classAnnotation, i), new.getExtension(BuiltInsProtoBuf.classAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(KlibMetadataProtoBuf.classAnnotation) != new.getExtensionCount(KlibMetadataProtoBuf.classAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(KlibMetadataProtoBuf.classAnnotation) - 1) {
                if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.classAnnotation, i), new.getExtension(KlibMetadataProtoBuf.classAnnotation, i))) return false
            }
        }

        return true
    }
    enum class ProtoBufClassKind {
        FLAGS,
        FQ_NAME,
        COMPANION_OBJECT_NAME,
        TYPE_PARAMETER_LIST,
        SUPERTYPE_LIST,
        SUPERTYPE_ID_LIST,
        NESTED_CLASS_NAME_LIST,
        CONTEXT_RECEIVER_TYPE_LIST,
        CONTEXT_RECEIVER_TYPE_ID_LIST,
        CONSTRUCTOR_LIST,
        FUNCTION_LIST,
        PROPERTY_LIST,
        TYPE_ALIAS_LIST,
        ENUM_ENTRY_LIST,
        SEALED_SUBCLASS_FQ_NAME_LIST,
        INLINE_CLASS_UNDERLYING_PROPERTY_NAME,
        INLINE_CLASS_UNDERLYING_TYPE,
        INLINE_CLASS_UNDERLYING_TYPE_ID,
        MULTI_FIELD_VALUE_CLASS_UNDERLYING_NAME_LIST,
        MULTI_FIELD_VALUE_CLASS_UNDERLYING_TYPE_LIST,
        MULTI_FIELD_VALUE_CLASS_UNDERLYING_TYPE_ID_LIST,
        VERSION_REQUIREMENT_LIST,
        VERSION_REQUIREMENT_TABLE,
        JVM_EXT_CLASS_MODULE_NAME,
        JVM_EXT_CLASS_LOCAL_VARIABLE_LIST,
        JVM_EXT_ANONYMOUS_OBJECT_ORIGIN_NAME,
        JVM_EXT_JVM_CLASS_FLAGS,
        JS_EXT_CLASS_ANNOTATION_LIST,
        JS_EXT_CLASS_CONTAINING_FILE_ID,
        JAVA_EXT_IS_PACKAGE_PRIVATE_CLASS,
        BUILT_INS_EXT_CLASS_ANNOTATION_LIST,
        KLIB_EXT_CLASS_ANNOTATION_LIST
    }

    fun difference(old: ProtoBuf.Class, new: ProtoBuf.Class): EnumSet<ProtoBufClassKind> {
        val result = EnumSet.noneOf(ProtoBufClassKind::class.java)

        if (old.hasFlags() != new.hasFlags()) result.add(ProtoBufClassKind.FLAGS)
        if (old.hasFlags()) {
            if (old.flags != new.flags) result.add(ProtoBufClassKind.FLAGS)
        }

        if (!checkClassIdEquals(old.fqName, new.fqName)) result.add(ProtoBufClassKind.FQ_NAME)

        if (old.hasCompanionObjectName() != new.hasCompanionObjectName()) result.add(ProtoBufClassKind.COMPANION_OBJECT_NAME)
        if (old.hasCompanionObjectName()) {
            if (!checkStringEquals(old.companionObjectName, new.companionObjectName)) result.add(ProtoBufClassKind.COMPANION_OBJECT_NAME)
        }

        if (!checkEqualsClassTypeParameter(old, new)) result.add(ProtoBufClassKind.TYPE_PARAMETER_LIST)

        if (!checkEqualsClassSupertype(old, new)) result.add(ProtoBufClassKind.SUPERTYPE_LIST)

        if (!checkEqualsClassSupertypeId(old, new)) result.add(ProtoBufClassKind.SUPERTYPE_ID_LIST)

        if (!checkEqualsClassNestedClassName(old, new)) result.add(ProtoBufClassKind.NESTED_CLASS_NAME_LIST)

        if (!checkEqualsClassContextReceiverType(old, new)) result.add(ProtoBufClassKind.CONTEXT_RECEIVER_TYPE_LIST)

        if (!checkEqualsClassContextReceiverTypeId(old, new)) result.add(ProtoBufClassKind.CONTEXT_RECEIVER_TYPE_ID_LIST)

        if (!checkEqualsClassConstructor(old, new)) result.add(ProtoBufClassKind.CONSTRUCTOR_LIST)

        if (!checkEqualsClassFunction(old, new)) result.add(ProtoBufClassKind.FUNCTION_LIST)

        if (!checkEqualsClassProperty(old, new)) result.add(ProtoBufClassKind.PROPERTY_LIST)

        if (!checkEqualsClassTypeAlias(old, new)) result.add(ProtoBufClassKind.TYPE_ALIAS_LIST)

        if (!checkEqualsClassEnumEntry(old, new)) result.add(ProtoBufClassKind.ENUM_ENTRY_LIST)

        if (!checkEqualsClassSealedSubclassFqName(old, new)) result.add(ProtoBufClassKind.SEALED_SUBCLASS_FQ_NAME_LIST)

        if (old.hasInlineClassUnderlyingPropertyName() != new.hasInlineClassUnderlyingPropertyName()) result.add(ProtoBufClassKind.INLINE_CLASS_UNDERLYING_PROPERTY_NAME)
        if (old.hasInlineClassUnderlyingPropertyName()) {
            if (!checkStringEquals(old.inlineClassUnderlyingPropertyName, new.inlineClassUnderlyingPropertyName)) result.add(ProtoBufClassKind.INLINE_CLASS_UNDERLYING_PROPERTY_NAME)
        }

        if (old.hasInlineClassUnderlyingType() != new.hasInlineClassUnderlyingType()) result.add(ProtoBufClassKind.INLINE_CLASS_UNDERLYING_TYPE)
        if (old.hasInlineClassUnderlyingType()) {
            if (!checkEquals(old.inlineClassUnderlyingType, new.inlineClassUnderlyingType)) result.add(ProtoBufClassKind.INLINE_CLASS_UNDERLYING_TYPE)
        }

        if (old.hasInlineClassUnderlyingTypeId() != new.hasInlineClassUnderlyingTypeId()) result.add(ProtoBufClassKind.INLINE_CLASS_UNDERLYING_TYPE_ID)
        if (old.hasInlineClassUnderlyingTypeId()) {
            if (!checkEquals(oldTypeTable.getType(old.inlineClassUnderlyingTypeId), newTypeTable.getType(new.inlineClassUnderlyingTypeId))) result.add(ProtoBufClassKind.INLINE_CLASS_UNDERLYING_TYPE_ID)
        }

        if (!checkEqualsClassMultiFieldValueClassUnderlyingName(old, new)) result.add(ProtoBufClassKind.MULTI_FIELD_VALUE_CLASS_UNDERLYING_NAME_LIST)

        if (!checkEqualsClassMultiFieldValueClassUnderlyingType(old, new)) result.add(ProtoBufClassKind.MULTI_FIELD_VALUE_CLASS_UNDERLYING_TYPE_LIST)

        if (!checkEqualsClassMultiFieldValueClassUnderlyingTypeId(old, new)) result.add(ProtoBufClassKind.MULTI_FIELD_VALUE_CLASS_UNDERLYING_TYPE_ID_LIST)

        if (!checkEqualsClassVersionRequirement(old, new)) result.add(ProtoBufClassKind.VERSION_REQUIREMENT_LIST)

        if (old.hasVersionRequirementTable() != new.hasVersionRequirementTable()) result.add(ProtoBufClassKind.VERSION_REQUIREMENT_TABLE)
        if (old.hasVersionRequirementTable()) {
            if (!checkEquals(old.versionRequirementTable, new.versionRequirementTable)) result.add(ProtoBufClassKind.VERSION_REQUIREMENT_TABLE)
        }

        if (old.hasExtension(JvmProtoBuf.classModuleName) != new.hasExtension(JvmProtoBuf.classModuleName)) result.add(ProtoBufClassKind.JVM_EXT_CLASS_MODULE_NAME)
        if (old.hasExtension(JvmProtoBuf.classModuleName)) {
            if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) result.add(ProtoBufClassKind.JVM_EXT_CLASS_MODULE_NAME)
        }

        if (old.getExtensionCount(JvmProtoBuf.classLocalVariable) != new.getExtensionCount(JvmProtoBuf.classLocalVariable)) {
            result.add(ProtoBufClassKind.JVM_EXT_CLASS_LOCAL_VARIABLE_LIST)
        }
        else {
            for(i in 0..old.getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
                if (!checkEquals(old.getExtension(JvmProtoBuf.classLocalVariable, i), new.getExtension(JvmProtoBuf.classLocalVariable, i))) result.add(ProtoBufClassKind.JVM_EXT_CLASS_LOCAL_VARIABLE_LIST)
            }
        }

        if (old.hasExtension(JvmProtoBuf.anonymousObjectOriginName) != new.hasExtension(JvmProtoBuf.anonymousObjectOriginName)) result.add(ProtoBufClassKind.JVM_EXT_ANONYMOUS_OBJECT_ORIGIN_NAME)
        if (old.hasExtension(JvmProtoBuf.anonymousObjectOriginName)) {
            if (!checkStringEquals(old.getExtension(JvmProtoBuf.anonymousObjectOriginName), new.getExtension(JvmProtoBuf.anonymousObjectOriginName))) result.add(ProtoBufClassKind.JVM_EXT_ANONYMOUS_OBJECT_ORIGIN_NAME)
        }

        if (old.hasExtension(JvmProtoBuf.jvmClassFlags) != new.hasExtension(JvmProtoBuf.jvmClassFlags)) result.add(ProtoBufClassKind.JVM_EXT_JVM_CLASS_FLAGS)
        if (old.hasExtension(JvmProtoBuf.jvmClassFlags)) {
            if (old.getExtension(JvmProtoBuf.jvmClassFlags) != new.getExtension(JvmProtoBuf.jvmClassFlags)) result.add(ProtoBufClassKind.JVM_EXT_JVM_CLASS_FLAGS)
        }

        if (old.getExtensionCount(JsProtoBuf.classAnnotation) != new.getExtensionCount(JsProtoBuf.classAnnotation)) {
            result.add(ProtoBufClassKind.JS_EXT_CLASS_ANNOTATION_LIST)
        }
        else {
            for(i in 0..old.getExtensionCount(JsProtoBuf.classAnnotation) - 1) {
                if (!checkEquals(old.getExtension(JsProtoBuf.classAnnotation, i), new.getExtension(JsProtoBuf.classAnnotation, i))) result.add(ProtoBufClassKind.JS_EXT_CLASS_ANNOTATION_LIST)
            }
        }

        if (old.hasExtension(JsProtoBuf.classContainingFileId) != new.hasExtension(JsProtoBuf.classContainingFileId)) result.add(ProtoBufClassKind.JS_EXT_CLASS_CONTAINING_FILE_ID)
        if (old.hasExtension(JsProtoBuf.classContainingFileId)) {
            if (old.getExtension(JsProtoBuf.classContainingFileId) != new.getExtension(JsProtoBuf.classContainingFileId)) result.add(ProtoBufClassKind.JS_EXT_CLASS_CONTAINING_FILE_ID)
        }

        if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateClass) != new.hasExtension(JavaClassProtoBuf.isPackagePrivateClass)) result.add(ProtoBufClassKind.JAVA_EXT_IS_PACKAGE_PRIVATE_CLASS)
        if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateClass)) {
            if (old.getExtension(JavaClassProtoBuf.isPackagePrivateClass) != new.getExtension(JavaClassProtoBuf.isPackagePrivateClass)) result.add(ProtoBufClassKind.JAVA_EXT_IS_PACKAGE_PRIVATE_CLASS)
        }

        if (old.getExtensionCount(BuiltInsProtoBuf.classAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.classAnnotation)) {
            result.add(ProtoBufClassKind.BUILT_INS_EXT_CLASS_ANNOTATION_LIST)
        }
        else {
            for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.classAnnotation) - 1) {
                if (!checkEquals(old.getExtension(BuiltInsProtoBuf.classAnnotation, i), new.getExtension(BuiltInsProtoBuf.classAnnotation, i))) result.add(ProtoBufClassKind.BUILT_INS_EXT_CLASS_ANNOTATION_LIST)
            }
        }

        if (old.getExtensionCount(KlibMetadataProtoBuf.classAnnotation) != new.getExtensionCount(KlibMetadataProtoBuf.classAnnotation)) {
            result.add(ProtoBufClassKind.KLIB_EXT_CLASS_ANNOTATION_LIST)
        }
        else {
            for(i in 0..old.getExtensionCount(KlibMetadataProtoBuf.classAnnotation) - 1) {
                if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.classAnnotation, i), new.getExtension(KlibMetadataProtoBuf.classAnnotation, i))) result.add(ProtoBufClassKind.KLIB_EXT_CLASS_ANNOTATION_LIST)
            }
        }

        return result
    }

    open fun checkEquals(old: ProtoBuf.Function, new: ProtoBuf.Function): Boolean {
        if (old.hasFlags() != new.hasFlags()) return false
        if (old.hasFlags()) {
            if (old.flags != new.flags) return false
        }

        if (old.hasOldFlags() != new.hasOldFlags()) return false
        if (old.hasOldFlags()) {
            if (old.oldFlags != new.oldFlags) return false
        }

        if (!checkStringEquals(old.name, new.name)) return false

        if (old.hasReturnType() != new.hasReturnType()) return false
        if (old.hasReturnType()) {
            if (!checkEquals(old.returnType, new.returnType)) return false
        }

        if (old.hasReturnTypeId() != new.hasReturnTypeId()) return false
        if (old.hasReturnTypeId()) {
            if (!checkEquals(oldTypeTable.getType(old.returnTypeId), newTypeTable.getType(new.returnTypeId))) return false
        }

        if (!checkEqualsFunctionTypeParameter(old, new)) return false

        if (old.hasReceiverType() != new.hasReceiverType()) return false
        if (old.hasReceiverType()) {
            if (!checkEquals(old.receiverType, new.receiverType)) return false
        }

        if (old.hasReceiverTypeId() != new.hasReceiverTypeId()) return false
        if (old.hasReceiverTypeId()) {
            if (!checkEquals(oldTypeTable.getType(old.receiverTypeId), newTypeTable.getType(new.receiverTypeId))) return false
        }

        if (!checkEqualsFunctionContextReceiverType(old, new)) return false

        if (!checkEqualsFunctionContextReceiverTypeId(old, new)) return false

        if (!checkEqualsFunctionValueParameter(old, new)) return false

        if (!checkEqualsFunctionVersionRequirement(old, new)) return false

        if (old.hasContract() != new.hasContract()) return false
        if (old.hasContract()) {
            if (!checkEquals(old.contract, new.contract)) return false
        }

        if (old.hasExtension(JvmProtoBuf.methodSignature) != new.hasExtension(JvmProtoBuf.methodSignature)) return false
        if (old.hasExtension(JvmProtoBuf.methodSignature)) {
            if (!checkEquals(old.getExtension(JvmProtoBuf.methodSignature), new.getExtension(JvmProtoBuf.methodSignature))) return false
        }

        if (old.hasExtension(JvmProtoBuf.lambdaClassOriginName) != new.hasExtension(JvmProtoBuf.lambdaClassOriginName)) return false
        if (old.hasExtension(JvmProtoBuf.lambdaClassOriginName)) {
            if (!checkStringEquals(old.getExtension(JvmProtoBuf.lambdaClassOriginName), new.getExtension(JvmProtoBuf.lambdaClassOriginName))) return false
        }

        if (old.getExtensionCount(JsProtoBuf.functionAnnotation) != new.getExtensionCount(JsProtoBuf.functionAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(JsProtoBuf.functionAnnotation) - 1) {
                if (!checkEquals(old.getExtension(JsProtoBuf.functionAnnotation, i), new.getExtension(JsProtoBuf.functionAnnotation, i))) return false
            }
        }

        if (old.hasExtension(JsProtoBuf.functionContainingFileId) != new.hasExtension(JsProtoBuf.functionContainingFileId)) return false
        if (old.hasExtension(JsProtoBuf.functionContainingFileId)) {
            if (old.getExtension(JsProtoBuf.functionContainingFileId) != new.getExtension(JsProtoBuf.functionContainingFileId)) return false
        }

        if (old.hasExtension(JavaClassProtoBuf.isStaticMethod) != new.hasExtension(JavaClassProtoBuf.isStaticMethod)) return false
        if (old.hasExtension(JavaClassProtoBuf.isStaticMethod)) {
            if (old.getExtension(JavaClassProtoBuf.isStaticMethod) != new.getExtension(JavaClassProtoBuf.isStaticMethod)) return false
        }

        if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateMethod) != new.hasExtension(JavaClassProtoBuf.isPackagePrivateMethod)) return false
        if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateMethod)) {
            if (old.getExtension(JavaClassProtoBuf.isPackagePrivateMethod) != new.getExtension(JavaClassProtoBuf.isPackagePrivateMethod)) return false
        }

        if (old.getExtensionCount(BuiltInsProtoBuf.functionAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.functionAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.functionAnnotation) - 1) {
                if (!checkEquals(old.getExtension(BuiltInsProtoBuf.functionAnnotation, i), new.getExtension(BuiltInsProtoBuf.functionAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(KlibMetadataProtoBuf.functionAnnotation) != new.getExtensionCount(KlibMetadataProtoBuf.functionAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(KlibMetadataProtoBuf.functionAnnotation) - 1) {
                if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.functionAnnotation, i), new.getExtension(KlibMetadataProtoBuf.functionAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(KlibMetadataProtoBuf.functionExtensionReceiverAnnotation) != new.getExtensionCount(KlibMetadataProtoBuf.functionExtensionReceiverAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(KlibMetadataProtoBuf.functionExtensionReceiverAnnotation) - 1) {
                if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.functionExtensionReceiverAnnotation, i), new.getExtension(KlibMetadataProtoBuf.functionExtensionReceiverAnnotation, i))) return false
            }
        }

        return true
    }

    open fun checkEquals(old: ProtoBuf.Property, new: ProtoBuf.Property): Boolean {
        if (old.hasFlags() != new.hasFlags()) return false
        if (old.hasFlags()) {
            if (old.flags != new.flags) return false
        }

        if (old.hasOldFlags() != new.hasOldFlags()) return false
        if (old.hasOldFlags()) {
            if (old.oldFlags != new.oldFlags) return false
        }

        if (!checkStringEquals(old.name, new.name)) return false

        if (old.hasReturnType() != new.hasReturnType()) return false
        if (old.hasReturnType()) {
            if (!checkEquals(old.returnType, new.returnType)) return false
        }

        if (old.hasReturnTypeId() != new.hasReturnTypeId()) return false
        if (old.hasReturnTypeId()) {
            if (!checkEquals(oldTypeTable.getType(old.returnTypeId), newTypeTable.getType(new.returnTypeId))) return false
        }

        if (!checkEqualsPropertyTypeParameter(old, new)) return false

        if (old.hasReceiverType() != new.hasReceiverType()) return false
        if (old.hasReceiverType()) {
            if (!checkEquals(old.receiverType, new.receiverType)) return false
        }

        if (old.hasReceiverTypeId() != new.hasReceiverTypeId()) return false
        if (old.hasReceiverTypeId()) {
            if (!checkEquals(oldTypeTable.getType(old.receiverTypeId), newTypeTable.getType(new.receiverTypeId))) return false
        }

        if (!checkEqualsPropertyContextReceiverType(old, new)) return false

        if (!checkEqualsPropertyContextReceiverTypeId(old, new)) return false

        if (old.hasSetterValueParameter() != new.hasSetterValueParameter()) return false
        if (old.hasSetterValueParameter()) {
            if (!checkEquals(old.setterValueParameter, new.setterValueParameter)) return false
        }

        if (old.hasGetterFlags() != new.hasGetterFlags()) return false
        if (old.hasGetterFlags()) {
            if (old.getterFlags != new.getterFlags) return false
        }

        if (old.hasSetterFlags() != new.hasSetterFlags()) return false
        if (old.hasSetterFlags()) {
            if (old.setterFlags != new.setterFlags) return false
        }

        if (!checkEqualsPropertyVersionRequirement(old, new)) return false

        if (old.hasExtension(JvmProtoBuf.propertySignature) != new.hasExtension(JvmProtoBuf.propertySignature)) return false
        if (old.hasExtension(JvmProtoBuf.propertySignature)) {
            if (!checkEquals(old.getExtension(JvmProtoBuf.propertySignature), new.getExtension(JvmProtoBuf.propertySignature))) return false
        }

        if (old.hasExtension(JvmProtoBuf.flags) != new.hasExtension(JvmProtoBuf.flags)) return false
        if (old.hasExtension(JvmProtoBuf.flags)) {
            if (old.getExtension(JvmProtoBuf.flags) != new.getExtension(JvmProtoBuf.flags)) return false
        }

        if (old.getExtensionCount(JsProtoBuf.propertyAnnotation) != new.getExtensionCount(JsProtoBuf.propertyAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(JsProtoBuf.propertyAnnotation) - 1) {
                if (!checkEquals(old.getExtension(JsProtoBuf.propertyAnnotation, i), new.getExtension(JsProtoBuf.propertyAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(JsProtoBuf.propertyGetterAnnotation) != new.getExtensionCount(JsProtoBuf.propertyGetterAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(JsProtoBuf.propertyGetterAnnotation) - 1) {
                if (!checkEquals(old.getExtension(JsProtoBuf.propertyGetterAnnotation, i), new.getExtension(JsProtoBuf.propertyGetterAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(JsProtoBuf.propertySetterAnnotation) != new.getExtensionCount(JsProtoBuf.propertySetterAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(JsProtoBuf.propertySetterAnnotation) - 1) {
                if (!checkEquals(old.getExtension(JsProtoBuf.propertySetterAnnotation, i), new.getExtension(JsProtoBuf.propertySetterAnnotation, i))) return false
            }
        }

        if (old.hasExtension(JsProtoBuf.compileTimeValue) != new.hasExtension(JsProtoBuf.compileTimeValue)) return false
        if (old.hasExtension(JsProtoBuf.compileTimeValue)) {
            if (!checkEquals(old.getExtension(JsProtoBuf.compileTimeValue), new.getExtension(JsProtoBuf.compileTimeValue))) return false
        }

        if (old.hasExtension(JsProtoBuf.propertyContainingFileId) != new.hasExtension(JsProtoBuf.propertyContainingFileId)) return false
        if (old.hasExtension(JsProtoBuf.propertyContainingFileId)) {
            if (old.getExtension(JsProtoBuf.propertyContainingFileId) != new.getExtension(JsProtoBuf.propertyContainingFileId)) return false
        }

        if (old.hasExtension(JavaClassProtoBuf.isStaticField) != new.hasExtension(JavaClassProtoBuf.isStaticField)) return false
        if (old.hasExtension(JavaClassProtoBuf.isStaticField)) {
            if (old.getExtension(JavaClassProtoBuf.isStaticField) != new.getExtension(JavaClassProtoBuf.isStaticField)) return false
        }

        if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateField) != new.hasExtension(JavaClassProtoBuf.isPackagePrivateField)) return false
        if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateField)) {
            if (old.getExtension(JavaClassProtoBuf.isPackagePrivateField) != new.getExtension(JavaClassProtoBuf.isPackagePrivateField)) return false
        }

        if (old.getExtensionCount(BuiltInsProtoBuf.propertyAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.propertyAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.propertyAnnotation) - 1) {
                if (!checkEquals(old.getExtension(BuiltInsProtoBuf.propertyAnnotation, i), new.getExtension(BuiltInsProtoBuf.propertyAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(BuiltInsProtoBuf.propertyGetterAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.propertyGetterAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.propertyGetterAnnotation) - 1) {
                if (!checkEquals(old.getExtension(BuiltInsProtoBuf.propertyGetterAnnotation, i), new.getExtension(BuiltInsProtoBuf.propertyGetterAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(BuiltInsProtoBuf.propertySetterAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.propertySetterAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.propertySetterAnnotation) - 1) {
                if (!checkEquals(old.getExtension(BuiltInsProtoBuf.propertySetterAnnotation, i), new.getExtension(BuiltInsProtoBuf.propertySetterAnnotation, i))) return false
            }
        }

        if (old.hasExtension(BuiltInsProtoBuf.compileTimeValue) != new.hasExtension(BuiltInsProtoBuf.compileTimeValue)) return false
        if (old.hasExtension(BuiltInsProtoBuf.compileTimeValue)) {
            if (!checkEquals(old.getExtension(BuiltInsProtoBuf.compileTimeValue), new.getExtension(BuiltInsProtoBuf.compileTimeValue))) return false
        }

        if (old.getExtensionCount(KlibMetadataProtoBuf.propertyAnnotation) != new.getExtensionCount(KlibMetadataProtoBuf.propertyAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(KlibMetadataProtoBuf.propertyAnnotation) - 1) {
                if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.propertyAnnotation, i), new.getExtension(KlibMetadataProtoBuf.propertyAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(KlibMetadataProtoBuf.propertyGetterAnnotation) != new.getExtensionCount(KlibMetadataProtoBuf.propertyGetterAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(KlibMetadataProtoBuf.propertyGetterAnnotation) - 1) {
                if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.propertyGetterAnnotation, i), new.getExtension(KlibMetadataProtoBuf.propertyGetterAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(KlibMetadataProtoBuf.propertySetterAnnotation) != new.getExtensionCount(KlibMetadataProtoBuf.propertySetterAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(KlibMetadataProtoBuf.propertySetterAnnotation) - 1) {
                if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.propertySetterAnnotation, i), new.getExtension(KlibMetadataProtoBuf.propertySetterAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(KlibMetadataProtoBuf.propertyBackingFieldAnnotation) != new.getExtensionCount(KlibMetadataProtoBuf.propertyBackingFieldAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(KlibMetadataProtoBuf.propertyBackingFieldAnnotation) - 1) {
                if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.propertyBackingFieldAnnotation, i), new.getExtension(KlibMetadataProtoBuf.propertyBackingFieldAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(KlibMetadataProtoBuf.propertyDelegatedFieldAnnotation) != new.getExtensionCount(KlibMetadataProtoBuf.propertyDelegatedFieldAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(KlibMetadataProtoBuf.propertyDelegatedFieldAnnotation) - 1) {
                if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.propertyDelegatedFieldAnnotation, i), new.getExtension(KlibMetadataProtoBuf.propertyDelegatedFieldAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(KlibMetadataProtoBuf.propertyExtensionReceiverAnnotation) != new.getExtensionCount(KlibMetadataProtoBuf.propertyExtensionReceiverAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(KlibMetadataProtoBuf.propertyExtensionReceiverAnnotation) - 1) {
                if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.propertyExtensionReceiverAnnotation, i), new.getExtension(KlibMetadataProtoBuf.propertyExtensionReceiverAnnotation, i))) return false
            }
        }

        if (old.hasExtension(KlibMetadataProtoBuf.compileTimeValue) != new.hasExtension(KlibMetadataProtoBuf.compileTimeValue)) return false
        if (old.hasExtension(KlibMetadataProtoBuf.compileTimeValue)) {
            if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.compileTimeValue), new.getExtension(KlibMetadataProtoBuf.compileTimeValue))) return false
        }

        return true
    }

    open fun checkEquals(old: ProtoBuf.TypeAlias, new: ProtoBuf.TypeAlias): Boolean {
        if (old.hasFlags() != new.hasFlags()) return false
        if (old.hasFlags()) {
            if (old.flags != new.flags) return false
        }

        if (!checkStringEquals(old.name, new.name)) return false

        if (!checkEqualsTypeAliasTypeParameter(old, new)) return false

        if (old.hasUnderlyingType() != new.hasUnderlyingType()) return false
        if (old.hasUnderlyingType()) {
            if (!checkEquals(old.underlyingType, new.underlyingType)) return false
        }

        if (old.hasUnderlyingTypeId() != new.hasUnderlyingTypeId()) return false
        if (old.hasUnderlyingTypeId()) {
            if (!checkEquals(oldTypeTable.getType(old.underlyingTypeId), newTypeTable.getType(new.underlyingTypeId))) return false
        }

        if (old.hasExpandedType() != new.hasExpandedType()) return false
        if (old.hasExpandedType()) {
            if (!checkEquals(old.expandedType, new.expandedType)) return false
        }

        if (old.hasExpandedTypeId() != new.hasExpandedTypeId()) return false
        if (old.hasExpandedTypeId()) {
            if (!checkEquals(oldTypeTable.getType(old.expandedTypeId), newTypeTable.getType(new.expandedTypeId))) return false
        }

        if (!checkEqualsTypeAliasAnnotation(old, new)) return false

        if (!checkEqualsTypeAliasVersionRequirement(old, new)) return false

        return true
    }

    open fun checkEquals(old: ProtoBuf.VersionRequirementTable, new: ProtoBuf.VersionRequirementTable): Boolean {
        if (!checkEqualsVersionRequirementTableRequirement(old, new)) return false

        return true
    }

    open fun checkEquals(old: ProtoBuf.TypeParameter, new: ProtoBuf.TypeParameter): Boolean {
        if (old.id != new.id) return false

        if (!checkStringEquals(old.name, new.name)) return false

        if (old.hasReified() != new.hasReified()) return false
        if (old.hasReified()) {
            if (old.reified != new.reified) return false
        }

        if (old.hasVariance() != new.hasVariance()) return false
        if (old.hasVariance()) {
            if (old.variance != new.variance) return false
        }

        if (!checkEqualsTypeParameterUpperBound(old, new)) return false

        if (!checkEqualsTypeParameterUpperBoundId(old, new)) return false

        if (old.getExtensionCount(JvmProtoBuf.typeParameterAnnotation) != new.getExtensionCount(JvmProtoBuf.typeParameterAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(JvmProtoBuf.typeParameterAnnotation) - 1) {
                if (!checkEquals(old.getExtension(JvmProtoBuf.typeParameterAnnotation, i), new.getExtension(JvmProtoBuf.typeParameterAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(JsProtoBuf.typeParameterAnnotation) != new.getExtensionCount(JsProtoBuf.typeParameterAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(JsProtoBuf.typeParameterAnnotation) - 1) {
                if (!checkEquals(old.getExtension(JsProtoBuf.typeParameterAnnotation, i), new.getExtension(JsProtoBuf.typeParameterAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(BuiltInsProtoBuf.typeParameterAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.typeParameterAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.typeParameterAnnotation) - 1) {
                if (!checkEquals(old.getExtension(BuiltInsProtoBuf.typeParameterAnnotation, i), new.getExtension(BuiltInsProtoBuf.typeParameterAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(KlibMetadataProtoBuf.typeParameterAnnotation) != new.getExtensionCount(KlibMetadataProtoBuf.typeParameterAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(KlibMetadataProtoBuf.typeParameterAnnotation) - 1) {
                if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.typeParameterAnnotation, i), new.getExtension(KlibMetadataProtoBuf.typeParameterAnnotation, i))) return false
            }
        }

        return true
    }

    open fun checkEquals(old: ProtoBuf.Type, new: ProtoBuf.Type): Boolean {
        if (!checkEqualsTypeArgument(old, new)) return false

        if (old.hasNullable() != new.hasNullable()) return false
        if (old.hasNullable()) {
            if (old.nullable != new.nullable) return false
        }

        if (old.hasFlexibleTypeCapabilitiesId() != new.hasFlexibleTypeCapabilitiesId()) return false
        if (old.hasFlexibleTypeCapabilitiesId()) {
            if (!checkStringEquals(old.flexibleTypeCapabilitiesId, new.flexibleTypeCapabilitiesId)) return false
        }

        if (old.hasFlexibleUpperBound() != new.hasFlexibleUpperBound()) return false
        if (old.hasFlexibleUpperBound()) {
            if (!checkEquals(old.flexibleUpperBound, new.flexibleUpperBound)) return false
        }

        if (old.hasFlexibleUpperBoundId() != new.hasFlexibleUpperBoundId()) return false
        if (old.hasFlexibleUpperBoundId()) {
            if (!checkEquals(oldTypeTable.getType(old.flexibleUpperBoundId), newTypeTable.getType(new.flexibleUpperBoundId))) return false
        }

        if (old.hasClassName() != new.hasClassName()) return false
        if (old.hasClassName()) {
            if (!checkClassIdEquals(old.className, new.className)) return false
        }

        if (old.hasTypeParameter() != new.hasTypeParameter()) return false
        if (old.hasTypeParameter()) {
            if (old.typeParameter != new.typeParameter) return false
        }

        if (old.hasTypeParameterName() != new.hasTypeParameterName()) return false
        if (old.hasTypeParameterName()) {
            if (!checkStringEquals(old.typeParameterName, new.typeParameterName)) return false
        }

        if (old.hasTypeAliasName() != new.hasTypeAliasName()) return false
        if (old.hasTypeAliasName()) {
            if (!checkClassIdEquals(old.typeAliasName, new.typeAliasName)) return false
        }

        if (old.hasOuterType() != new.hasOuterType()) return false
        if (old.hasOuterType()) {
            if (!checkEquals(old.outerType, new.outerType)) return false
        }

        if (old.hasOuterTypeId() != new.hasOuterTypeId()) return false
        if (old.hasOuterTypeId()) {
            if (!checkEquals(oldTypeTable.getType(old.outerTypeId), newTypeTable.getType(new.outerTypeId))) return false
        }

        if (old.hasAbbreviatedType() != new.hasAbbreviatedType()) return false
        if (old.hasAbbreviatedType()) {
            if (!checkEquals(old.abbreviatedType, new.abbreviatedType)) return false
        }

        if (old.hasAbbreviatedTypeId() != new.hasAbbreviatedTypeId()) return false
        if (old.hasAbbreviatedTypeId()) {
            if (!checkEquals(oldTypeTable.getType(old.abbreviatedTypeId), newTypeTable.getType(new.abbreviatedTypeId))) return false
        }

        if (old.hasFlags() != new.hasFlags()) return false
        if (old.hasFlags()) {
            if (old.flags != new.flags) return false
        }

        if (old.getExtensionCount(JvmProtoBuf.typeAnnotation) != new.getExtensionCount(JvmProtoBuf.typeAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(JvmProtoBuf.typeAnnotation) - 1) {
                if (!checkEquals(old.getExtension(JvmProtoBuf.typeAnnotation, i), new.getExtension(JvmProtoBuf.typeAnnotation, i))) return false
            }
        }

        if (old.hasExtension(JvmProtoBuf.isRaw) != new.hasExtension(JvmProtoBuf.isRaw)) return false
        if (old.hasExtension(JvmProtoBuf.isRaw)) {
            if (old.getExtension(JvmProtoBuf.isRaw) != new.getExtension(JvmProtoBuf.isRaw)) return false
        }

        if (old.getExtensionCount(JsProtoBuf.typeAnnotation) != new.getExtensionCount(JsProtoBuf.typeAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(JsProtoBuf.typeAnnotation) - 1) {
                if (!checkEquals(old.getExtension(JsProtoBuf.typeAnnotation, i), new.getExtension(JsProtoBuf.typeAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(BuiltInsProtoBuf.typeAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.typeAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.typeAnnotation) - 1) {
                if (!checkEquals(old.getExtension(BuiltInsProtoBuf.typeAnnotation, i), new.getExtension(BuiltInsProtoBuf.typeAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(KlibMetadataProtoBuf.typeAnnotation) != new.getExtensionCount(KlibMetadataProtoBuf.typeAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(KlibMetadataProtoBuf.typeAnnotation) - 1) {
                if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.typeAnnotation, i), new.getExtension(KlibMetadataProtoBuf.typeAnnotation, i))) return false
            }
        }

        return true
    }

    open fun checkEquals(old: ProtoBuf.Constructor, new: ProtoBuf.Constructor): Boolean {
        if (old.hasFlags() != new.hasFlags()) return false
        if (old.hasFlags()) {
            if (old.flags != new.flags) return false
        }

        if (!checkEqualsConstructorValueParameter(old, new)) return false

        if (!checkEqualsConstructorVersionRequirement(old, new)) return false

        if (old.hasExtension(JvmProtoBuf.constructorSignature) != new.hasExtension(JvmProtoBuf.constructorSignature)) return false
        if (old.hasExtension(JvmProtoBuf.constructorSignature)) {
            if (!checkEquals(old.getExtension(JvmProtoBuf.constructorSignature), new.getExtension(JvmProtoBuf.constructorSignature))) return false
        }

        if (old.getExtensionCount(JsProtoBuf.constructorAnnotation) != new.getExtensionCount(JsProtoBuf.constructorAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(JsProtoBuf.constructorAnnotation) - 1) {
                if (!checkEquals(old.getExtension(JsProtoBuf.constructorAnnotation, i), new.getExtension(JsProtoBuf.constructorAnnotation, i))) return false
            }
        }

        if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateConstructor) != new.hasExtension(JavaClassProtoBuf.isPackagePrivateConstructor)) return false
        if (old.hasExtension(JavaClassProtoBuf.isPackagePrivateConstructor)) {
            if (old.getExtension(JavaClassProtoBuf.isPackagePrivateConstructor) != new.getExtension(JavaClassProtoBuf.isPackagePrivateConstructor)) return false
        }

        if (old.getExtensionCount(BuiltInsProtoBuf.constructorAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.constructorAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.constructorAnnotation) - 1) {
                if (!checkEquals(old.getExtension(BuiltInsProtoBuf.constructorAnnotation, i), new.getExtension(BuiltInsProtoBuf.constructorAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(KlibMetadataProtoBuf.constructorAnnotation) != new.getExtensionCount(KlibMetadataProtoBuf.constructorAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(KlibMetadataProtoBuf.constructorAnnotation) - 1) {
                if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.constructorAnnotation, i), new.getExtension(KlibMetadataProtoBuf.constructorAnnotation, i))) return false
            }
        }

        return true
    }

    open fun checkEquals(old: ProtoBuf.EnumEntry, new: ProtoBuf.EnumEntry): Boolean {
        if (old.hasName() != new.hasName()) return false
        if (old.hasName()) {
            if (!checkStringEquals(old.name, new.name)) return false
        }

        if (old.getExtensionCount(JsProtoBuf.enumEntryAnnotation) != new.getExtensionCount(JsProtoBuf.enumEntryAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(JsProtoBuf.enumEntryAnnotation) - 1) {
                if (!checkEquals(old.getExtension(JsProtoBuf.enumEntryAnnotation, i), new.getExtension(JsProtoBuf.enumEntryAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(BuiltInsProtoBuf.enumEntryAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.enumEntryAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.enumEntryAnnotation) - 1) {
                if (!checkEquals(old.getExtension(BuiltInsProtoBuf.enumEntryAnnotation, i), new.getExtension(BuiltInsProtoBuf.enumEntryAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(KlibMetadataProtoBuf.enumEntryAnnotation) != new.getExtensionCount(KlibMetadataProtoBuf.enumEntryAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(KlibMetadataProtoBuf.enumEntryAnnotation) - 1) {
                if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.enumEntryAnnotation, i), new.getExtension(KlibMetadataProtoBuf.enumEntryAnnotation, i))) return false
            }
        }

        if (old.hasExtension(KlibMetadataProtoBuf.enumEntryOrdinal) != new.hasExtension(KlibMetadataProtoBuf.enumEntryOrdinal)) return false
        if (old.hasExtension(KlibMetadataProtoBuf.enumEntryOrdinal)) {
            if (old.getExtension(KlibMetadataProtoBuf.enumEntryOrdinal) != new.getExtension(KlibMetadataProtoBuf.enumEntryOrdinal)) return false
        }

        return true
    }

    open fun checkEquals(old: ProtoBuf.Annotation, new: ProtoBuf.Annotation): Boolean {
        if (!checkClassIdEquals(old.id, new.id)) return false

        if (!checkEqualsAnnotationArgument(old, new)) return false

        return true
    }

    open fun checkEquals(old: ProtoBuf.ValueParameter, new: ProtoBuf.ValueParameter): Boolean {
        if (old.hasFlags() != new.hasFlags()) return false
        if (old.hasFlags()) {
            if (old.flags != new.flags) return false
        }

        if (!checkStringEquals(old.name, new.name)) return false

        if (old.hasType() != new.hasType()) return false
        if (old.hasType()) {
            if (!checkEquals(old.type, new.type)) return false
        }

        if (old.hasTypeId() != new.hasTypeId()) return false
        if (old.hasTypeId()) {
            if (!checkEquals(oldTypeTable.getType(old.typeId), newTypeTable.getType(new.typeId))) return false
        }

        if (old.hasVarargElementType() != new.hasVarargElementType()) return false
        if (old.hasVarargElementType()) {
            if (!checkEquals(old.varargElementType, new.varargElementType)) return false
        }

        if (old.hasVarargElementTypeId() != new.hasVarargElementTypeId()) return false
        if (old.hasVarargElementTypeId()) {
            if (!checkEquals(oldTypeTable.getType(old.varargElementTypeId), newTypeTable.getType(new.varargElementTypeId))) return false
        }

        if (old.getExtensionCount(JsProtoBuf.parameterAnnotation) != new.getExtensionCount(JsProtoBuf.parameterAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(JsProtoBuf.parameterAnnotation) - 1) {
                if (!checkEquals(old.getExtension(JsProtoBuf.parameterAnnotation, i), new.getExtension(JsProtoBuf.parameterAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(BuiltInsProtoBuf.parameterAnnotation) != new.getExtensionCount(BuiltInsProtoBuf.parameterAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(BuiltInsProtoBuf.parameterAnnotation) - 1) {
                if (!checkEquals(old.getExtension(BuiltInsProtoBuf.parameterAnnotation, i), new.getExtension(BuiltInsProtoBuf.parameterAnnotation, i))) return false
            }
        }

        if (old.getExtensionCount(KlibMetadataProtoBuf.parameterAnnotation) != new.getExtensionCount(KlibMetadataProtoBuf.parameterAnnotation)) {
            return false
        }
        else {
            for(i in 0..old.getExtensionCount(KlibMetadataProtoBuf.parameterAnnotation) - 1) {
                if (!checkEquals(old.getExtension(KlibMetadataProtoBuf.parameterAnnotation, i), new.getExtension(KlibMetadataProtoBuf.parameterAnnotation, i))) return false
            }
        }

        return true
    }

    open fun checkEquals(old: ProtoBuf.Contract, new: ProtoBuf.Contract): Boolean {
        if (!checkEqualsContractEffect(old, new)) return false

        return true
    }

    open fun checkEquals(old: JvmProtoBuf.JvmMethodSignature, new: JvmProtoBuf.JvmMethodSignature): Boolean {
        if (old.hasName() != new.hasName()) return false
        if (old.hasName()) {
            if (!checkStringEquals(old.name, new.name)) return false
        }

        if (old.hasDesc() != new.hasDesc()) return false
        if (old.hasDesc()) {
            if (!checkStringEquals(old.desc, new.desc)) return false
        }

        return true
    }

    open fun checkEquals(old: JvmProtoBuf.JvmPropertySignature, new: JvmProtoBuf.JvmPropertySignature): Boolean {
        if (old.hasField() != new.hasField()) return false
        if (old.hasField()) {
            if (!checkEquals(old.field, new.field)) return false
        }

        if (old.hasSyntheticMethod() != new.hasSyntheticMethod()) return false
        if (old.hasSyntheticMethod()) {
            if (!checkEquals(old.syntheticMethod, new.syntheticMethod)) return false
        }

        if (old.hasGetter() != new.hasGetter()) return false
        if (old.hasGetter()) {
            if (!checkEquals(old.getter, new.getter)) return false
        }

        if (old.hasSetter() != new.hasSetter()) return false
        if (old.hasSetter()) {
            if (!checkEquals(old.setter, new.setter)) return false
        }

        if (old.hasDelegateMethod() != new.hasDelegateMethod()) return false
        if (old.hasDelegateMethod()) {
            if (!checkEquals(old.delegateMethod, new.delegateMethod)) return false
        }

        return true
    }

    open fun checkEquals(old: ProtoBuf.Annotation.Argument.Value, new: ProtoBuf.Annotation.Argument.Value): Boolean {
        if (old.hasType() != new.hasType()) return false
        if (old.hasType()) {
            if (old.type != new.type) return false
        }

        if (old.hasIntValue() != new.hasIntValue()) return false
        if (old.hasIntValue()) {
            if (old.intValue != new.intValue) return false
        }

        if (old.hasFloatValue() != new.hasFloatValue()) return false
        if (old.hasFloatValue()) {
            if (old.floatValue != new.floatValue) return false
        }

        if (old.hasDoubleValue() != new.hasDoubleValue()) return false
        if (old.hasDoubleValue()) {
            if (old.doubleValue != new.doubleValue) return false
        }

        if (old.hasStringValue() != new.hasStringValue()) return false
        if (old.hasStringValue()) {
            if (!checkStringEquals(old.stringValue, new.stringValue)) return false
        }

        if (old.hasClassId() != new.hasClassId()) return false
        if (old.hasClassId()) {
            if (!checkClassIdEquals(old.classId, new.classId)) return false
        }

        if (old.hasEnumValueId() != new.hasEnumValueId()) return false
        if (old.hasEnumValueId()) {
            if (!checkStringEquals(old.enumValueId, new.enumValueId)) return false
        }

        if (old.hasAnnotation() != new.hasAnnotation()) return false
        if (old.hasAnnotation()) {
            if (!checkEquals(old.annotation, new.annotation)) return false
        }

        if (!checkEqualsAnnotationArgumentValueArrayElement(old, new)) return false

        if (old.hasArrayDimensionCount() != new.hasArrayDimensionCount()) return false
        if (old.hasArrayDimensionCount()) {
            if (old.arrayDimensionCount != new.arrayDimensionCount) return false
        }

        if (old.hasFlags() != new.hasFlags()) return false
        if (old.hasFlags()) {
            if (old.flags != new.flags) return false
        }

        return true
    }

    open fun checkEquals(old: ProtoBuf.VersionRequirement, new: ProtoBuf.VersionRequirement): Boolean {
        if (old.hasVersion() != new.hasVersion()) return false
        if (old.hasVersion()) {
            if (old.version != new.version) return false
        }

        if (old.hasVersionFull() != new.hasVersionFull()) return false
        if (old.hasVersionFull()) {
            if (old.versionFull != new.versionFull) return false
        }

        if (old.hasLevel() != new.hasLevel()) return false
        if (old.hasLevel()) {
            if (old.level != new.level) return false
        }

        if (old.hasErrorCode() != new.hasErrorCode()) return false
        if (old.hasErrorCode()) {
            if (old.errorCode != new.errorCode) return false
        }

        if (old.hasMessage() != new.hasMessage()) return false
        if (old.hasMessage()) {
            if (!checkStringEquals(old.message, new.message)) return false
        }

        if (old.hasVersionKind() != new.hasVersionKind()) return false
        if (old.hasVersionKind()) {
            if (old.versionKind != new.versionKind) return false
        }

        return true
    }

    open fun checkEquals(old: ProtoBuf.Type.Argument, new: ProtoBuf.Type.Argument): Boolean {
        if (old.hasProjection() != new.hasProjection()) return false
        if (old.hasProjection()) {
            if (old.projection != new.projection) return false
        }

        if (old.hasType() != new.hasType()) return false
        if (old.hasType()) {
            if (!checkEquals(old.type, new.type)) return false
        }

        if (old.hasTypeId() != new.hasTypeId()) return false
        if (old.hasTypeId()) {
            if (!checkEquals(oldTypeTable.getType(old.typeId), newTypeTable.getType(new.typeId))) return false
        }

        return true
    }

    open fun checkEquals(old: ProtoBuf.Annotation.Argument, new: ProtoBuf.Annotation.Argument): Boolean {
        if (!checkStringEquals(old.nameId, new.nameId)) return false

        if (!checkEquals(old.value, new.value)) return false

        return true
    }

    open fun checkEquals(old: ProtoBuf.Effect, new: ProtoBuf.Effect): Boolean {
        if (old.hasEffectType() != new.hasEffectType()) return false
        if (old.hasEffectType()) {
            if (old.effectType != new.effectType) return false
        }

        if (!checkEqualsEffectEffectConstructorArgument(old, new)) return false

        if (old.hasConclusionOfConditionalEffect() != new.hasConclusionOfConditionalEffect()) return false
        if (old.hasConclusionOfConditionalEffect()) {
            if (!checkEquals(old.conclusionOfConditionalEffect, new.conclusionOfConditionalEffect)) return false
        }

        if (old.hasKind() != new.hasKind()) return false
        if (old.hasKind()) {
            if (old.kind != new.kind) return false
        }

        return true
    }

    open fun checkEquals(old: JvmProtoBuf.JvmFieldSignature, new: JvmProtoBuf.JvmFieldSignature): Boolean {
        if (old.hasName() != new.hasName()) return false
        if (old.hasName()) {
            if (!checkStringEquals(old.name, new.name)) return false
        }

        if (old.hasDesc() != new.hasDesc()) return false
        if (old.hasDesc()) {
            if (!checkStringEquals(old.desc, new.desc)) return false
        }

        return true
    }

    open fun checkEquals(old: ProtoBuf.Expression, new: ProtoBuf.Expression): Boolean {
        if (old.hasFlags() != new.hasFlags()) return false
        if (old.hasFlags()) {
            if (old.flags != new.flags) return false
        }

        if (old.hasValueParameterReference() != new.hasValueParameterReference()) return false
        if (old.hasValueParameterReference()) {
            if (old.valueParameterReference != new.valueParameterReference) return false
        }

        if (old.hasConstantValue() != new.hasConstantValue()) return false
        if (old.hasConstantValue()) {
            if (old.constantValue != new.constantValue) return false
        }

        if (old.hasIsInstanceType() != new.hasIsInstanceType()) return false
        if (old.hasIsInstanceType()) {
            if (!checkEquals(old.isInstanceType, new.isInstanceType)) return false
        }

        if (old.hasIsInstanceTypeId() != new.hasIsInstanceTypeId()) return false
        if (old.hasIsInstanceTypeId()) {
            if (!checkEquals(oldTypeTable.getType(old.isInstanceTypeId), newTypeTable.getType(new.isInstanceTypeId))) return false
        }

        if (!checkEqualsExpressionAndArgument(old, new)) return false

        if (!checkEqualsExpressionOrArgument(old, new)) return false

        return true
    }

    open fun checkEqualsPackageFunction(old: ProtoBuf.Package, new: ProtoBuf.Package): Boolean {
        if (old.functionCount != new.functionCount) return false

        for(i in 0..old.functionCount - 1) {
            if (!checkEquals(old.getFunction(i), new.getFunction(i))) return false
        }

        return true
    }

    open fun checkEqualsPackageProperty(old: ProtoBuf.Package, new: ProtoBuf.Package): Boolean {
        if (old.propertyCount != new.propertyCount) return false

        for(i in 0..old.propertyCount - 1) {
            if (!checkEquals(old.getProperty(i), new.getProperty(i))) return false
        }

        return true
    }

    open fun checkEqualsPackageTypeAlias(old: ProtoBuf.Package, new: ProtoBuf.Package): Boolean {
        if (old.typeAliasCount != new.typeAliasCount) return false

        for(i in 0..old.typeAliasCount - 1) {
            if (!checkEquals(old.getTypeAlias(i), new.getTypeAlias(i))) return false
        }

        return true
    }

    open fun checkEqualsClassTypeParameter(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.typeParameterCount != new.typeParameterCount) return false

        for(i in 0..old.typeParameterCount - 1) {
            if (!checkEquals(old.getTypeParameter(i), new.getTypeParameter(i))) return false
        }

        return true
    }

    open fun checkEqualsClassSupertype(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.supertypeCount != new.supertypeCount) return false

        for(i in 0..old.supertypeCount - 1) {
            if (!checkEquals(old.getSupertype(i), new.getSupertype(i))) return false
        }

        return true
    }

    open fun checkEqualsClassSupertypeId(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.supertypeIdCount != new.supertypeIdCount) return false

        for(i in 0..old.supertypeIdCount - 1) {
            if (!checkEquals(oldTypeTable.getType(old.getSupertypeId(i)), newTypeTable.getType(new.getSupertypeId(i)))) return false
        }

        return true
    }

    open fun checkEqualsClassNestedClassName(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.nestedClassNameCount != new.nestedClassNameCount) return false

        for(i in 0..old.nestedClassNameCount - 1) {
            if (!checkStringEquals(old.getNestedClassName(i), new.getNestedClassName(i))) return false
        }

        return true
    }

    open fun checkEqualsClassContextReceiverType(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.contextReceiverTypeCount != new.contextReceiverTypeCount) return false

        for(i in 0..old.contextReceiverTypeCount - 1) {
            if (!checkEquals(old.getContextReceiverType(i), new.getContextReceiverType(i))) return false
        }

        return true
    }

    open fun checkEqualsClassContextReceiverTypeId(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.contextReceiverTypeIdCount != new.contextReceiverTypeIdCount) return false

        for(i in 0..old.contextReceiverTypeIdCount - 1) {
            if (!checkEquals(oldTypeTable.getType(old.getContextReceiverTypeId(i)), newTypeTable.getType(new.getContextReceiverTypeId(i)))) return false
        }

        return true
    }

    open fun checkEqualsClassConstructor(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.constructorCount != new.constructorCount) return false

        for(i in 0..old.constructorCount - 1) {
            if (!checkEquals(old.getConstructor(i), new.getConstructor(i))) return false
        }

        return true
    }

    open fun checkEqualsClassFunction(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.functionCount != new.functionCount) return false

        for(i in 0..old.functionCount - 1) {
            if (!checkEquals(old.getFunction(i), new.getFunction(i))) return false
        }

        return true
    }

    open fun checkEqualsClassProperty(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.propertyCount != new.propertyCount) return false

        for(i in 0..old.propertyCount - 1) {
            if (!checkEquals(old.getProperty(i), new.getProperty(i))) return false
        }

        return true
    }

    open fun checkEqualsClassTypeAlias(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.typeAliasCount != new.typeAliasCount) return false

        for(i in 0..old.typeAliasCount - 1) {
            if (!checkEquals(old.getTypeAlias(i), new.getTypeAlias(i))) return false
        }

        return true
    }

    open fun checkEqualsClassEnumEntry(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.enumEntryCount != new.enumEntryCount) return false

        for(i in 0..old.enumEntryCount - 1) {
            if (!checkEquals(old.getEnumEntry(i), new.getEnumEntry(i))) return false
        }

        return true
    }

    open fun checkEqualsClassSealedSubclassFqName(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.sealedSubclassFqNameCount != new.sealedSubclassFqNameCount) return false

        for(i in 0..old.sealedSubclassFqNameCount - 1) {
            if (!checkClassIdEquals(old.getSealedSubclassFqName(i), new.getSealedSubclassFqName(i))) return false
        }

        return true
    }

    open fun checkEqualsClassMultiFieldValueClassUnderlyingName(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.multiFieldValueClassUnderlyingNameCount != new.multiFieldValueClassUnderlyingNameCount) return false

        for(i in 0..old.multiFieldValueClassUnderlyingNameCount - 1) {
            if (!checkStringEquals(old.getMultiFieldValueClassUnderlyingName(i), new.getMultiFieldValueClassUnderlyingName(i))) return false
        }

        return true
    }

    open fun checkEqualsClassMultiFieldValueClassUnderlyingType(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.multiFieldValueClassUnderlyingTypeCount != new.multiFieldValueClassUnderlyingTypeCount) return false

        for(i in 0..old.multiFieldValueClassUnderlyingTypeCount - 1) {
            if (!checkEquals(old.getMultiFieldValueClassUnderlyingType(i), new.getMultiFieldValueClassUnderlyingType(i))) return false
        }

        return true
    }

    open fun checkEqualsClassMultiFieldValueClassUnderlyingTypeId(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.multiFieldValueClassUnderlyingTypeIdCount != new.multiFieldValueClassUnderlyingTypeIdCount) return false

        for(i in 0..old.multiFieldValueClassUnderlyingTypeIdCount - 1) {
            if (!checkEquals(oldTypeTable.getType(old.getMultiFieldValueClassUnderlyingTypeId(i)), newTypeTable.getType(new.getMultiFieldValueClassUnderlyingTypeId(i)))) return false
        }

        return true
    }

    open fun checkEqualsClassVersionRequirement(old: ProtoBuf.Class, new: ProtoBuf.Class): Boolean {
        if (old.versionRequirementCount != new.versionRequirementCount) return false

        for(i in 0..old.versionRequirementCount - 1) {
            if (old.getVersionRequirement(i) != new.getVersionRequirement(i)) return false
        }

        return true
    }

    open fun checkEqualsFunctionTypeParameter(old: ProtoBuf.Function, new: ProtoBuf.Function): Boolean {
        if (old.typeParameterCount != new.typeParameterCount) return false

        for(i in 0..old.typeParameterCount - 1) {
            if (!checkEquals(old.getTypeParameter(i), new.getTypeParameter(i))) return false
        }

        return true
    }

    open fun checkEqualsFunctionContextReceiverType(old: ProtoBuf.Function, new: ProtoBuf.Function): Boolean {
        if (old.contextReceiverTypeCount != new.contextReceiverTypeCount) return false

        for(i in 0..old.contextReceiverTypeCount - 1) {
            if (!checkEquals(old.getContextReceiverType(i), new.getContextReceiverType(i))) return false
        }

        return true
    }

    open fun checkEqualsFunctionContextReceiverTypeId(old: ProtoBuf.Function, new: ProtoBuf.Function): Boolean {
        if (old.contextReceiverTypeIdCount != new.contextReceiverTypeIdCount) return false

        for(i in 0..old.contextReceiverTypeIdCount - 1) {
            if (!checkEquals(oldTypeTable.getType(old.getContextReceiverTypeId(i)), newTypeTable.getType(new.getContextReceiverTypeId(i)))) return false
        }

        return true
    }

    open fun checkEqualsFunctionValueParameter(old: ProtoBuf.Function, new: ProtoBuf.Function): Boolean {
        if (old.valueParameterCount != new.valueParameterCount) return false

        for(i in 0..old.valueParameterCount - 1) {
            if (!checkEquals(old.getValueParameter(i), new.getValueParameter(i))) return false
        }

        return true
    }

    open fun checkEqualsFunctionVersionRequirement(old: ProtoBuf.Function, new: ProtoBuf.Function): Boolean {
        if (old.versionRequirementCount != new.versionRequirementCount) return false

        for(i in 0..old.versionRequirementCount - 1) {
            if (old.getVersionRequirement(i) != new.getVersionRequirement(i)) return false
        }

        return true
    }

    open fun checkEqualsPropertyTypeParameter(old: ProtoBuf.Property, new: ProtoBuf.Property): Boolean {
        if (old.typeParameterCount != new.typeParameterCount) return false

        for(i in 0..old.typeParameterCount - 1) {
            if (!checkEquals(old.getTypeParameter(i), new.getTypeParameter(i))) return false
        }

        return true
    }

    open fun checkEqualsPropertyContextReceiverType(old: ProtoBuf.Property, new: ProtoBuf.Property): Boolean {
        if (old.contextReceiverTypeCount != new.contextReceiverTypeCount) return false

        for(i in 0..old.contextReceiverTypeCount - 1) {
            if (!checkEquals(old.getContextReceiverType(i), new.getContextReceiverType(i))) return false
        }

        return true
    }

    open fun checkEqualsPropertyContextReceiverTypeId(old: ProtoBuf.Property, new: ProtoBuf.Property): Boolean {
        if (old.contextReceiverTypeIdCount != new.contextReceiverTypeIdCount) return false

        for(i in 0..old.contextReceiverTypeIdCount - 1) {
            if (!checkEquals(oldTypeTable.getType(old.getContextReceiverTypeId(i)), newTypeTable.getType(new.getContextReceiverTypeId(i)))) return false
        }

        return true
    }

    open fun checkEqualsPropertyVersionRequirement(old: ProtoBuf.Property, new: ProtoBuf.Property): Boolean {
        if (old.versionRequirementCount != new.versionRequirementCount) return false

        for(i in 0..old.versionRequirementCount - 1) {
            if (old.getVersionRequirement(i) != new.getVersionRequirement(i)) return false
        }

        return true
    }

    open fun checkEqualsTypeAliasTypeParameter(old: ProtoBuf.TypeAlias, new: ProtoBuf.TypeAlias): Boolean {
        if (old.typeParameterCount != new.typeParameterCount) return false

        for(i in 0..old.typeParameterCount - 1) {
            if (!checkEquals(old.getTypeParameter(i), new.getTypeParameter(i))) return false
        }

        return true
    }

    open fun checkEqualsTypeAliasAnnotation(old: ProtoBuf.TypeAlias, new: ProtoBuf.TypeAlias): Boolean {
        if (old.annotationCount != new.annotationCount) return false

        for(i in 0..old.annotationCount - 1) {
            if (!checkEquals(old.getAnnotation(i), new.getAnnotation(i))) return false
        }

        return true
    }

    open fun checkEqualsTypeAliasVersionRequirement(old: ProtoBuf.TypeAlias, new: ProtoBuf.TypeAlias): Boolean {
        if (old.versionRequirementCount != new.versionRequirementCount) return false

        for(i in 0..old.versionRequirementCount - 1) {
            if (old.getVersionRequirement(i) != new.getVersionRequirement(i)) return false
        }

        return true
    }

    open fun checkEqualsVersionRequirementTableRequirement(old: ProtoBuf.VersionRequirementTable, new: ProtoBuf.VersionRequirementTable): Boolean {
        if (old.requirementCount != new.requirementCount) return false

        for(i in 0..old.requirementCount - 1) {
            if (!checkEquals(old.getRequirement(i), new.getRequirement(i))) return false
        }

        return true
    }

    open fun checkEqualsTypeParameterUpperBound(old: ProtoBuf.TypeParameter, new: ProtoBuf.TypeParameter): Boolean {
        if (old.upperBoundCount != new.upperBoundCount) return false

        for(i in 0..old.upperBoundCount - 1) {
            if (!checkEquals(old.getUpperBound(i), new.getUpperBound(i))) return false
        }

        return true
    }

    open fun checkEqualsTypeParameterUpperBoundId(old: ProtoBuf.TypeParameter, new: ProtoBuf.TypeParameter): Boolean {
        if (old.upperBoundIdCount != new.upperBoundIdCount) return false

        for(i in 0..old.upperBoundIdCount - 1) {
            if (!checkEquals(oldTypeTable.getType(old.getUpperBoundId(i)), newTypeTable.getType(new.getUpperBoundId(i)))) return false
        }

        return true
    }

    open fun checkEqualsTypeArgument(old: ProtoBuf.Type, new: ProtoBuf.Type): Boolean {
        if (old.argumentCount != new.argumentCount) return false

        for(i in 0..old.argumentCount - 1) {
            if (!checkEquals(old.getArgument(i), new.getArgument(i))) return false
        }

        return true
    }

    open fun checkEqualsConstructorValueParameter(old: ProtoBuf.Constructor, new: ProtoBuf.Constructor): Boolean {
        if (old.valueParameterCount != new.valueParameterCount) return false

        for(i in 0..old.valueParameterCount - 1) {
            if (!checkEquals(old.getValueParameter(i), new.getValueParameter(i))) return false
        }

        return true
    }

    open fun checkEqualsConstructorVersionRequirement(old: ProtoBuf.Constructor, new: ProtoBuf.Constructor): Boolean {
        if (old.versionRequirementCount != new.versionRequirementCount) return false

        for(i in 0..old.versionRequirementCount - 1) {
            if (old.getVersionRequirement(i) != new.getVersionRequirement(i)) return false
        }

        return true
    }

    open fun checkEqualsAnnotationArgument(old: ProtoBuf.Annotation, new: ProtoBuf.Annotation): Boolean {
        if (old.argumentCount != new.argumentCount) return false

        for(i in 0..old.argumentCount - 1) {
            if (!checkEquals(old.getArgument(i), new.getArgument(i))) return false
        }

        return true
    }

    open fun checkEqualsContractEffect(old: ProtoBuf.Contract, new: ProtoBuf.Contract): Boolean {
        if (old.effectCount != new.effectCount) return false

        for(i in 0..old.effectCount - 1) {
            if (!checkEquals(old.getEffect(i), new.getEffect(i))) return false
        }

        return true
    }

    open fun checkEqualsAnnotationArgumentValueArrayElement(old: ProtoBuf.Annotation.Argument.Value, new: ProtoBuf.Annotation.Argument.Value): Boolean {
        if (old.arrayElementCount != new.arrayElementCount) return false

        for(i in 0..old.arrayElementCount - 1) {
            if (!checkEquals(old.getArrayElement(i), new.getArrayElement(i))) return false
        }

        return true
    }

    open fun checkEqualsEffectEffectConstructorArgument(old: ProtoBuf.Effect, new: ProtoBuf.Effect): Boolean {
        if (old.effectConstructorArgumentCount != new.effectConstructorArgumentCount) return false

        for(i in 0..old.effectConstructorArgumentCount - 1) {
            if (!checkEquals(old.getEffectConstructorArgument(i), new.getEffectConstructorArgument(i))) return false
        }

        return true
    }

    open fun checkEqualsExpressionAndArgument(old: ProtoBuf.Expression, new: ProtoBuf.Expression): Boolean {
        if (old.andArgumentCount != new.andArgumentCount) return false

        for(i in 0..old.andArgumentCount - 1) {
            if (!checkEquals(old.getAndArgument(i), new.getAndArgument(i))) return false
        }

        return true
    }

    open fun checkEqualsExpressionOrArgument(old: ProtoBuf.Expression, new: ProtoBuf.Expression): Boolean {
        if (old.orArgumentCount != new.orArgumentCount) return false

        for(i in 0..old.orArgumentCount - 1) {
            if (!checkEquals(old.getOrArgument(i), new.getOrArgument(i))) return false
        }

        return true
    }

    fun oldGetTypeById(id: Int): ProtoBuf.Type = oldTypeTable.getType(id) ?: error("Unknown type id: $id")
    fun newGetTypeById(id: Int): ProtoBuf.Type = newTypeTable.getType(id) ?: error("Unknown type id: $id")

    fun oldGetIndexOfString(index: Int): Int = getIndexOfString(index, oldStringIndexesMap, oldNameResolver)
    fun newGetIndexOfString(index: Int): Int = getIndexOfString(index, newStringIndexesMap, newNameResolver)

    fun getIndexOfString(index: Int, map: MutableMap<Int, Int>, nameResolver: NameResolver): Int {
        map[index]?.let { return it }

        val result = strings.intern(nameResolver.getString(index))
        map[index] = result
        return result
    }

    fun oldGetIndexOfClassId(index: Int): Int = getIndexOfClassId(index, oldClassIdIndexesMap, oldNameResolver)
    fun newGetIndexOfClassId(index: Int): Int = getIndexOfClassId(index, newClassIdIndexesMap, newNameResolver)

    fun getIndexOfClassId(index: Int, map: MutableMap<Int, Int>, nameResolver: NameResolver): Int {
        map[index]?.let { return it }

        val result = classIds.intern(nameResolver.getClassId(index))
        map[index] = result
        return result
    }

    private fun checkStringEquals(old: Int, new: Int): Boolean {
       return oldGetIndexOfString(old) == newGetIndexOfString(new)
    }

    private fun checkClassIdEquals(old: Int, new: Int): Boolean {
       return oldGetIndexOfClassId(old) == newGetIndexOfClassId(new)
    }
}

fun ProtoBuf.Package.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    for(i in 0..functionCount - 1) {
        hashCode = 31 * hashCode + getFunction(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..propertyCount - 1) {
        hashCode = 31 * hashCode + getProperty(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..typeAliasCount - 1) {
        hashCode = 31 * hashCode + getTypeAlias(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasVersionRequirementTable()) {
        hashCode = 31 * hashCode + versionRequirementTable.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(JvmProtoBuf.packageModuleName)) {
        hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.packageModuleName))
    }

    for(i in 0..getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
        hashCode = 31 * hashCode + getExtension(JvmProtoBuf.packageLocalVariable, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(JsProtoBuf.packageFqName)) {
        hashCode = 31 * hashCode + getExtension(JsProtoBuf.packageFqName)
    }

    if (hasExtension(BuiltInsProtoBuf.packageFqName)) {
        hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.packageFqName)
    }

    if (hasExtension(KlibMetadataProtoBuf.packageFqName)) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.packageFqName)
    }

    return hashCode
}

fun ProtoBuf.Class.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    if (hasFlags()) {
        hashCode = 31 * hashCode + flags
    }

    hashCode = 31 * hashCode + fqNameIndexes(fqName)

    if (hasCompanionObjectName()) {
        hashCode = 31 * hashCode + stringIndexes(companionObjectName)
    }

    for(i in 0..typeParameterCount - 1) {
        hashCode = 31 * hashCode + getTypeParameter(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..supertypeCount - 1) {
        hashCode = 31 * hashCode + getSupertype(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..supertypeIdCount - 1) {
        hashCode = 31 * hashCode + typeById(getSupertypeId(i)).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..nestedClassNameCount - 1) {
        hashCode = 31 * hashCode + stringIndexes(getNestedClassName(i))
    }

    for(i in 0..contextReceiverTypeCount - 1) {
        hashCode = 31 * hashCode + getContextReceiverType(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..contextReceiverTypeIdCount - 1) {
        hashCode = 31 * hashCode + typeById(getContextReceiverTypeId(i)).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..constructorCount - 1) {
        hashCode = 31 * hashCode + getConstructor(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..functionCount - 1) {
        hashCode = 31 * hashCode + getFunction(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..propertyCount - 1) {
        hashCode = 31 * hashCode + getProperty(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..typeAliasCount - 1) {
        hashCode = 31 * hashCode + getTypeAlias(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..enumEntryCount - 1) {
        hashCode = 31 * hashCode + getEnumEntry(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..sealedSubclassFqNameCount - 1) {
        hashCode = 31 * hashCode + fqNameIndexes(getSealedSubclassFqName(i))
    }

    if (hasInlineClassUnderlyingPropertyName()) {
        hashCode = 31 * hashCode + stringIndexes(inlineClassUnderlyingPropertyName)
    }

    if (hasInlineClassUnderlyingType()) {
        hashCode = 31 * hashCode + inlineClassUnderlyingType.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasInlineClassUnderlyingTypeId()) {
        hashCode = 31 * hashCode + typeById(inlineClassUnderlyingTypeId).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..multiFieldValueClassUnderlyingNameCount - 1) {
        hashCode = 31 * hashCode + stringIndexes(getMultiFieldValueClassUnderlyingName(i))
    }

    for(i in 0..multiFieldValueClassUnderlyingTypeCount - 1) {
        hashCode = 31 * hashCode + getMultiFieldValueClassUnderlyingType(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..multiFieldValueClassUnderlyingTypeIdCount - 1) {
        hashCode = 31 * hashCode + typeById(getMultiFieldValueClassUnderlyingTypeId(i)).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..versionRequirementCount - 1) {
        hashCode = 31 * hashCode + getVersionRequirement(i)
    }

    if (hasVersionRequirementTable()) {
        hashCode = 31 * hashCode + versionRequirementTable.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(JvmProtoBuf.classModuleName)) {
        hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.classModuleName))
    }

    for(i in 0..getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
        hashCode = 31 * hashCode + getExtension(JvmProtoBuf.classLocalVariable, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(JvmProtoBuf.anonymousObjectOriginName)) {
        hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.anonymousObjectOriginName))
    }

    if (hasExtension(JvmProtoBuf.jvmClassFlags)) {
        hashCode = 31 * hashCode + getExtension(JvmProtoBuf.jvmClassFlags)
    }

    for(i in 0..getExtensionCount(JsProtoBuf.classAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(JsProtoBuf.classAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(JsProtoBuf.classContainingFileId)) {
        hashCode = 31 * hashCode + getExtension(JsProtoBuf.classContainingFileId)
    }

    if (hasExtension(JavaClassProtoBuf.isPackagePrivateClass)) {
        hashCode = 31 * hashCode + getExtension(JavaClassProtoBuf.isPackagePrivateClass).hashCode()
    }

    for(i in 0..getExtensionCount(BuiltInsProtoBuf.classAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.classAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(KlibMetadataProtoBuf.classAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.classAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    return hashCode
}

fun ProtoBuf.Function.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    if (hasFlags()) {
        hashCode = 31 * hashCode + flags
    }

    if (hasOldFlags()) {
        hashCode = 31 * hashCode + oldFlags
    }

    hashCode = 31 * hashCode + stringIndexes(name)

    if (hasReturnType()) {
        hashCode = 31 * hashCode + returnType.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasReturnTypeId()) {
        hashCode = 31 * hashCode + typeById(returnTypeId).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..typeParameterCount - 1) {
        hashCode = 31 * hashCode + getTypeParameter(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasReceiverType()) {
        hashCode = 31 * hashCode + receiverType.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasReceiverTypeId()) {
        hashCode = 31 * hashCode + typeById(receiverTypeId).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..contextReceiverTypeCount - 1) {
        hashCode = 31 * hashCode + getContextReceiverType(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..contextReceiverTypeIdCount - 1) {
        hashCode = 31 * hashCode + typeById(getContextReceiverTypeId(i)).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..valueParameterCount - 1) {
        hashCode = 31 * hashCode + getValueParameter(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..versionRequirementCount - 1) {
        hashCode = 31 * hashCode + getVersionRequirement(i)
    }

    if (hasContract()) {
        hashCode = 31 * hashCode + contract.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(JvmProtoBuf.methodSignature)) {
        hashCode = 31 * hashCode + getExtension(JvmProtoBuf.methodSignature).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(JvmProtoBuf.lambdaClassOriginName)) {
        hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.lambdaClassOriginName))
    }

    for(i in 0..getExtensionCount(JsProtoBuf.functionAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(JsProtoBuf.functionAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(JsProtoBuf.functionContainingFileId)) {
        hashCode = 31 * hashCode + getExtension(JsProtoBuf.functionContainingFileId)
    }

    if (hasExtension(JavaClassProtoBuf.isStaticMethod)) {
        hashCode = 31 * hashCode + getExtension(JavaClassProtoBuf.isStaticMethod).hashCode()
    }

    if (hasExtension(JavaClassProtoBuf.isPackagePrivateMethod)) {
        hashCode = 31 * hashCode + getExtension(JavaClassProtoBuf.isPackagePrivateMethod).hashCode()
    }

    for(i in 0..getExtensionCount(BuiltInsProtoBuf.functionAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.functionAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(KlibMetadataProtoBuf.functionAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.functionAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(KlibMetadataProtoBuf.functionExtensionReceiverAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.functionExtensionReceiverAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    return hashCode
}

fun ProtoBuf.Property.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    if (hasFlags()) {
        hashCode = 31 * hashCode + flags
    }

    if (hasOldFlags()) {
        hashCode = 31 * hashCode + oldFlags
    }

    hashCode = 31 * hashCode + stringIndexes(name)

    if (hasReturnType()) {
        hashCode = 31 * hashCode + returnType.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasReturnTypeId()) {
        hashCode = 31 * hashCode + typeById(returnTypeId).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..typeParameterCount - 1) {
        hashCode = 31 * hashCode + getTypeParameter(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasReceiverType()) {
        hashCode = 31 * hashCode + receiverType.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasReceiverTypeId()) {
        hashCode = 31 * hashCode + typeById(receiverTypeId).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..contextReceiverTypeCount - 1) {
        hashCode = 31 * hashCode + getContextReceiverType(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..contextReceiverTypeIdCount - 1) {
        hashCode = 31 * hashCode + typeById(getContextReceiverTypeId(i)).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasSetterValueParameter()) {
        hashCode = 31 * hashCode + setterValueParameter.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasGetterFlags()) {
        hashCode = 31 * hashCode + getterFlags
    }

    if (hasSetterFlags()) {
        hashCode = 31 * hashCode + setterFlags
    }

    for(i in 0..versionRequirementCount - 1) {
        hashCode = 31 * hashCode + getVersionRequirement(i)
    }

    if (hasExtension(JvmProtoBuf.propertySignature)) {
        hashCode = 31 * hashCode + getExtension(JvmProtoBuf.propertySignature).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(JvmProtoBuf.flags)) {
        hashCode = 31 * hashCode + getExtension(JvmProtoBuf.flags)
    }

    for(i in 0..getExtensionCount(JsProtoBuf.propertyAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(JsProtoBuf.propertyAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(JsProtoBuf.propertyGetterAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(JsProtoBuf.propertyGetterAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(JsProtoBuf.propertySetterAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(JsProtoBuf.propertySetterAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(JsProtoBuf.compileTimeValue)) {
        hashCode = 31 * hashCode + getExtension(JsProtoBuf.compileTimeValue).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(JsProtoBuf.propertyContainingFileId)) {
        hashCode = 31 * hashCode + getExtension(JsProtoBuf.propertyContainingFileId)
    }

    if (hasExtension(JavaClassProtoBuf.isStaticField)) {
        hashCode = 31 * hashCode + getExtension(JavaClassProtoBuf.isStaticField).hashCode()
    }

    if (hasExtension(JavaClassProtoBuf.isPackagePrivateField)) {
        hashCode = 31 * hashCode + getExtension(JavaClassProtoBuf.isPackagePrivateField).hashCode()
    }

    for(i in 0..getExtensionCount(BuiltInsProtoBuf.propertyAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.propertyAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(BuiltInsProtoBuf.propertyGetterAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.propertyGetterAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(BuiltInsProtoBuf.propertySetterAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.propertySetterAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(BuiltInsProtoBuf.compileTimeValue)) {
        hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.compileTimeValue).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(KlibMetadataProtoBuf.propertyAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.propertyAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(KlibMetadataProtoBuf.propertyGetterAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.propertyGetterAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(KlibMetadataProtoBuf.propertySetterAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.propertySetterAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(KlibMetadataProtoBuf.propertyBackingFieldAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.propertyBackingFieldAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(KlibMetadataProtoBuf.propertyDelegatedFieldAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.propertyDelegatedFieldAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(KlibMetadataProtoBuf.propertyExtensionReceiverAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.propertyExtensionReceiverAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(KlibMetadataProtoBuf.compileTimeValue)) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.compileTimeValue).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    return hashCode
}

fun ProtoBuf.TypeAlias.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    if (hasFlags()) {
        hashCode = 31 * hashCode + flags
    }

    hashCode = 31 * hashCode + stringIndexes(name)

    for(i in 0..typeParameterCount - 1) {
        hashCode = 31 * hashCode + getTypeParameter(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasUnderlyingType()) {
        hashCode = 31 * hashCode + underlyingType.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasUnderlyingTypeId()) {
        hashCode = 31 * hashCode + typeById(underlyingTypeId).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExpandedType()) {
        hashCode = 31 * hashCode + expandedType.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExpandedTypeId()) {
        hashCode = 31 * hashCode + typeById(expandedTypeId).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..annotationCount - 1) {
        hashCode = 31 * hashCode + getAnnotation(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..versionRequirementCount - 1) {
        hashCode = 31 * hashCode + getVersionRequirement(i)
    }

    return hashCode
}

fun ProtoBuf.VersionRequirementTable.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    for(i in 0..requirementCount - 1) {
        hashCode = 31 * hashCode + getRequirement(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    return hashCode
}

fun ProtoBuf.TypeParameter.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    hashCode = 31 * hashCode + id

    hashCode = 31 * hashCode + stringIndexes(name)

    if (hasReified()) {
        hashCode = 31 * hashCode + reified.hashCode()
    }

    if (hasVariance()) {
        hashCode = 31 * hashCode + variance.hashCode()
    }

    for(i in 0..upperBoundCount - 1) {
        hashCode = 31 * hashCode + getUpperBound(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..upperBoundIdCount - 1) {
        hashCode = 31 * hashCode + typeById(getUpperBoundId(i)).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(JvmProtoBuf.typeParameterAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(JvmProtoBuf.typeParameterAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(JsProtoBuf.typeParameterAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(JsProtoBuf.typeParameterAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(BuiltInsProtoBuf.typeParameterAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.typeParameterAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(KlibMetadataProtoBuf.typeParameterAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.typeParameterAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    return hashCode
}

fun ProtoBuf.Type.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    for(i in 0..argumentCount - 1) {
        hashCode = 31 * hashCode + getArgument(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasNullable()) {
        hashCode = 31 * hashCode + nullable.hashCode()
    }

    if (hasFlexibleTypeCapabilitiesId()) {
        hashCode = 31 * hashCode + stringIndexes(flexibleTypeCapabilitiesId)
    }

    if (hasFlexibleUpperBound()) {
        hashCode = 31 * hashCode + flexibleUpperBound.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasFlexibleUpperBoundId()) {
        hashCode = 31 * hashCode + typeById(flexibleUpperBoundId).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasClassName()) {
        hashCode = 31 * hashCode + fqNameIndexes(className)
    }

    if (hasTypeParameter()) {
        hashCode = 31 * hashCode + typeParameter
    }

    if (hasTypeParameterName()) {
        hashCode = 31 * hashCode + stringIndexes(typeParameterName)
    }

    if (hasTypeAliasName()) {
        hashCode = 31 * hashCode + fqNameIndexes(typeAliasName)
    }

    if (hasOuterType()) {
        hashCode = 31 * hashCode + outerType.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasOuterTypeId()) {
        hashCode = 31 * hashCode + typeById(outerTypeId).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasAbbreviatedType()) {
        hashCode = 31 * hashCode + abbreviatedType.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasAbbreviatedTypeId()) {
        hashCode = 31 * hashCode + typeById(abbreviatedTypeId).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasFlags()) {
        hashCode = 31 * hashCode + flags
    }

    for(i in 0..getExtensionCount(JvmProtoBuf.typeAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(JvmProtoBuf.typeAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(JvmProtoBuf.isRaw)) {
        hashCode = 31 * hashCode + getExtension(JvmProtoBuf.isRaw).hashCode()
    }

    for(i in 0..getExtensionCount(JsProtoBuf.typeAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(JsProtoBuf.typeAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(BuiltInsProtoBuf.typeAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.typeAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(KlibMetadataProtoBuf.typeAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.typeAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    return hashCode
}

fun ProtoBuf.Constructor.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    if (hasFlags()) {
        hashCode = 31 * hashCode + flags
    }

    for(i in 0..valueParameterCount - 1) {
        hashCode = 31 * hashCode + getValueParameter(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..versionRequirementCount - 1) {
        hashCode = 31 * hashCode + getVersionRequirement(i)
    }

    if (hasExtension(JvmProtoBuf.constructorSignature)) {
        hashCode = 31 * hashCode + getExtension(JvmProtoBuf.constructorSignature).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(JsProtoBuf.constructorAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(JsProtoBuf.constructorAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(JavaClassProtoBuf.isPackagePrivateConstructor)) {
        hashCode = 31 * hashCode + getExtension(JavaClassProtoBuf.isPackagePrivateConstructor).hashCode()
    }

    for(i in 0..getExtensionCount(BuiltInsProtoBuf.constructorAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.constructorAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(KlibMetadataProtoBuf.constructorAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.constructorAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    return hashCode
}

fun ProtoBuf.EnumEntry.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    if (hasName()) {
        hashCode = 31 * hashCode + stringIndexes(name)
    }

    for(i in 0..getExtensionCount(JsProtoBuf.enumEntryAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(JsProtoBuf.enumEntryAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(BuiltInsProtoBuf.enumEntryAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.enumEntryAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(KlibMetadataProtoBuf.enumEntryAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.enumEntryAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasExtension(KlibMetadataProtoBuf.enumEntryOrdinal)) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.enumEntryOrdinal)
    }

    return hashCode
}

fun ProtoBuf.Annotation.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    hashCode = 31 * hashCode + fqNameIndexes(id)

    for(i in 0..argumentCount - 1) {
        hashCode = 31 * hashCode + getArgument(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    return hashCode
}

fun ProtoBuf.ValueParameter.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    if (hasFlags()) {
        hashCode = 31 * hashCode + flags
    }

    hashCode = 31 * hashCode + stringIndexes(name)

    if (hasType()) {
        hashCode = 31 * hashCode + type.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasTypeId()) {
        hashCode = 31 * hashCode + typeById(typeId).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasVarargElementType()) {
        hashCode = 31 * hashCode + varargElementType.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasVarargElementTypeId()) {
        hashCode = 31 * hashCode + typeById(varargElementTypeId).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(JsProtoBuf.parameterAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(JsProtoBuf.parameterAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(BuiltInsProtoBuf.parameterAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(BuiltInsProtoBuf.parameterAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..getExtensionCount(KlibMetadataProtoBuf.parameterAnnotation) - 1) {
        hashCode = 31 * hashCode + getExtension(KlibMetadataProtoBuf.parameterAnnotation, i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    return hashCode
}

fun ProtoBuf.Contract.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    for(i in 0..effectCount - 1) {
        hashCode = 31 * hashCode + getEffect(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    return hashCode
}

fun JvmProtoBuf.JvmMethodSignature.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    if (hasName()) {
        hashCode = 31 * hashCode + stringIndexes(name)
    }

    if (hasDesc()) {
        hashCode = 31 * hashCode + stringIndexes(desc)
    }

    return hashCode
}

fun JvmProtoBuf.JvmPropertySignature.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    if (hasField()) {
        hashCode = 31 * hashCode + field.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasSyntheticMethod()) {
        hashCode = 31 * hashCode + syntheticMethod.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasGetter()) {
        hashCode = 31 * hashCode + getter.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasSetter()) {
        hashCode = 31 * hashCode + setter.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasDelegateMethod()) {
        hashCode = 31 * hashCode + delegateMethod.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    return hashCode
}

fun ProtoBuf.Annotation.Argument.Value.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    if (hasType()) {
        hashCode = 31 * hashCode + type.hashCode()
    }

    if (hasIntValue()) {
        hashCode = 31 * hashCode + intValue.hashCode()
    }

    if (hasFloatValue()) {
        hashCode = 31 * hashCode + floatValue.hashCode()
    }

    if (hasDoubleValue()) {
        hashCode = 31 * hashCode + doubleValue.hashCode()
    }

    if (hasStringValue()) {
        hashCode = 31 * hashCode + stringIndexes(stringValue)
    }

    if (hasClassId()) {
        hashCode = 31 * hashCode + fqNameIndexes(classId)
    }

    if (hasEnumValueId()) {
        hashCode = 31 * hashCode + stringIndexes(enumValueId)
    }

    if (hasAnnotation()) {
        hashCode = 31 * hashCode + annotation.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..arrayElementCount - 1) {
        hashCode = 31 * hashCode + getArrayElement(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasArrayDimensionCount()) {
        hashCode = 31 * hashCode + arrayDimensionCount
    }

    if (hasFlags()) {
        hashCode = 31 * hashCode + flags
    }

    return hashCode
}

fun ProtoBuf.VersionRequirement.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    if (hasVersion()) {
        hashCode = 31 * hashCode + version
    }

    if (hasVersionFull()) {
        hashCode = 31 * hashCode + versionFull
    }

    if (hasLevel()) {
        hashCode = 31 * hashCode + level.hashCode()
    }

    if (hasErrorCode()) {
        hashCode = 31 * hashCode + errorCode
    }

    if (hasMessage()) {
        hashCode = 31 * hashCode + stringIndexes(message)
    }

    if (hasVersionKind()) {
        hashCode = 31 * hashCode + versionKind.hashCode()
    }

    return hashCode
}

fun ProtoBuf.Type.Argument.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    if (hasProjection()) {
        hashCode = 31 * hashCode + projection.hashCode()
    }

    if (hasType()) {
        hashCode = 31 * hashCode + type.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasTypeId()) {
        hashCode = 31 * hashCode + typeById(typeId).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    return hashCode
}

fun ProtoBuf.Annotation.Argument.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    hashCode = 31 * hashCode + stringIndexes(nameId)

    hashCode = 31 * hashCode + value.hashCode(stringIndexes, fqNameIndexes, typeById)

    return hashCode
}

fun ProtoBuf.Effect.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    if (hasEffectType()) {
        hashCode = 31 * hashCode + effectType.hashCode()
    }

    for(i in 0..effectConstructorArgumentCount - 1) {
        hashCode = 31 * hashCode + getEffectConstructorArgument(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasConclusionOfConditionalEffect()) {
        hashCode = 31 * hashCode + conclusionOfConditionalEffect.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasKind()) {
        hashCode = 31 * hashCode + kind.hashCode()
    }

    return hashCode
}

fun JvmProtoBuf.JvmFieldSignature.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    if (hasName()) {
        hashCode = 31 * hashCode + stringIndexes(name)
    }

    if (hasDesc()) {
        hashCode = 31 * hashCode + stringIndexes(desc)
    }

    return hashCode
}

fun ProtoBuf.Expression.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) -> Int, typeById: (Int) -> ProtoBuf.Type): Int {
    var hashCode = 1

    if (hasFlags()) {
        hashCode = 31 * hashCode + flags
    }

    if (hasValueParameterReference()) {
        hashCode = 31 * hashCode + valueParameterReference
    }

    if (hasConstantValue()) {
        hashCode = 31 * hashCode + constantValue.hashCode()
    }

    if (hasIsInstanceType()) {
        hashCode = 31 * hashCode + isInstanceType.hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    if (hasIsInstanceTypeId()) {
        hashCode = 31 * hashCode + typeById(isInstanceTypeId).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..andArgumentCount - 1) {
        hashCode = 31 * hashCode + getAndArgument(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    for(i in 0..orArgumentCount - 1) {
        hashCode = 31 * hashCode + getOrArgument(i).hashCode(stringIndexes, fqNameIndexes, typeById)
    }

    return hashCode
}
